2020-12-23 11:35:49 +01:00
// Copyright (c) Umbraco.
// See LICENSE for more details.
2020-12-17 16:27:28 +11:00
using System.Linq ;
2020-06-17 16:39:28 +02:00
using System.Net ;
using System.Net.Http ;
using System.Threading.Tasks ;
using Newtonsoft.Json ;
using NUnit.Framework ;
2022-06-21 08:09:38 +02:00
using Umbraco.Cms.Core ;
2021-02-18 11:06:02 +01:00
using Umbraco.Cms.Core.Models ;
using Umbraco.Cms.Core.Models.ContentEditing ;
using Umbraco.Cms.Core.Services ;
2023-09-12 14:16:27 +02:00
using Umbraco.Cms.Tests.Common.Attributes ;
2021-02-18 11:06:02 +01:00
using Umbraco.Cms.Tests.Common.Builders ;
using Umbraco.Cms.Tests.Common.Builders.Extensions ;
using Umbraco.Cms.Tests.Integration.TestServerTest ;
using Umbraco.Cms.Web.BackOffice.Controllers ;
using Umbraco.Cms.Web.Common.Formatters ;
using Umbraco.Extensions ;
2020-06-17 16:39:28 +02:00
2022-06-21 08:09:38 +02:00
namespace Umbraco.Cms.Tests.Integration.Umbraco.Web.BackOffice.Controllers ;
[TestFixture]
public class ContentControllerTests : UmbracoTestServerTestBase
2020-06-17 16:39:28 +02:00
{
2022-06-21 08:09:38 +02:00
private const string UsIso = "en-US" ;
private const string DkIso = "da-DK" ;
/// <summary>
/// Returns 404 if the content wasn't found based on the ID specified
/// </summary>
[Test]
2023-09-12 14:16:27 +02:00
[LongRunning]
2022-06-21 08:09:38 +02:00
public async Task PostSave_Validate_Existing_Content ( )
2020-06-17 16:39:28 +02:00
{
2022-06-21 08:09:38 +02:00
var localizationService = GetRequiredService < ILocalizationService > ( ) ;
// Add another language
localizationService . Save ( new LanguageBuilder ( )
. WithCultureInfo ( DkIso )
. WithIsDefault ( false )
. Build ( ) ) ;
var url = PrepareApiControllerUrl < ContentController > ( x = > x . PostSave ( null ) ) ;
var contentService = GetRequiredService < IContentService > ( ) ;
var contentTypeService = GetRequiredService < IContentTypeService > ( ) ;
var contentType = new ContentTypeBuilder ( )
. WithId ( 0 )
. AddPropertyType ( )
. WithAlias ( "title" )
. WithValueStorageType ( ValueStorageType . Integer )
. WithPropertyEditorAlias ( Constants . PropertyEditors . Aliases . TextBox )
. WithName ( "Title" )
. Done ( )
. WithContentVariation ( ContentVariation . Nothing )
. Build ( ) ;
contentTypeService . Save ( contentType ) ;
var content = new ContentBuilder ( )
. WithId ( 0 )
. WithName ( "Invariant" )
. WithContentType ( contentType )
. AddPropertyData ( )
. WithKeyValue ( "title" , "Cool invariant title" )
. Done ( )
. Build ( ) ;
contentService . SaveAndPublish ( content ) ;
var model = new ContentItemSaveBuilder ( )
. WithContent ( content )
. WithId ( - 1337 ) // HERE We overwrite the Id, so we don't expect to find it on the server
. Build ( ) ;
// Act
2022-06-21 08:20:25 +02:00
var response =
await Client . PostAsync ( url , new MultipartFormDataContent { { new StringContent ( JsonConvert . SerializeObject ( model ) ) , "contentItem" } } ) ;
2022-06-21 08:09:38 +02:00
// Assert
Assert . AreEqual ( HttpStatusCode . NotFound , response . StatusCode ) ;
//// Assert.AreEqual(")]}',\n{\"Message\":\"content was not found\"}", response.Item1.Content.ReadAsStringAsync().Result);
////
//// //var obj = JsonConvert.DeserializeObject<PagedResult<UserDisplay>>(response.Item2);
//// //Assert.AreEqual(0, obj.TotalItems);
}
[Test]
2023-09-12 14:16:27 +02:00
[LongRunning]
2022-06-21 08:09:38 +02:00
public async Task PostSave_Validate_At_Least_One_Variant_Flagged_For_Saving ( )
{
var localizationService = GetRequiredService < ILocalizationService > ( ) ;
// Add another language
localizationService . Save ( new LanguageBuilder ( )
. WithCultureInfo ( DkIso )
. WithIsDefault ( false )
. Build ( ) ) ;
var url = PrepareApiControllerUrl < ContentController > ( x = > x . PostSave ( null ) ) ;
var contentTypeService = GetRequiredService < IContentTypeService > ( ) ;
var contentType = new ContentTypeBuilder ( )
. WithId ( 0 )
. AddPropertyType ( )
. WithAlias ( "title" )
. WithValueStorageType ( ValueStorageType . Integer )
. WithPropertyEditorAlias ( Constants . PropertyEditors . Aliases . TextBox )
. WithName ( "Title" )
. Done ( )
. WithContentVariation ( ContentVariation . Nothing )
. Build ( ) ;
contentTypeService . Save ( contentType ) ;
var contentService = GetRequiredService < IContentService > ( ) ;
var content = new ContentBuilder ( )
. WithId ( 0 )
. WithName ( "Invariant" )
. WithContentType ( contentType )
. AddPropertyData ( )
. WithKeyValue ( "title" , "Cool invariant title" )
. Done ( )
. Build ( ) ;
contentService . SaveAndPublish ( content ) ;
var model = new ContentItemSaveBuilder ( )
. WithContent ( content )
. Build ( ) ;
// HERE we force the test to fail
model . Variants = model . Variants . Select ( x = >
2020-06-17 16:39:28 +02:00
{
2022-06-21 08:09:38 +02:00
x . Save = false ;
return x ;
} ) ;
2020-06-17 16:39:28 +02:00
2022-06-21 08:09:38 +02:00
// Act
2022-06-21 08:20:25 +02:00
var response =
await Client . PostAsync ( url , new MultipartFormDataContent { { new StringContent ( JsonConvert . SerializeObject ( model ) ) , "contentItem" } } ) ;
2022-06-21 08:09:38 +02:00
// Assert
var body = await response . Content . ReadAsStringAsync ( ) ;
Assert . Multiple ( ( ) = >
{
2020-12-17 16:27:28 +11:00
Assert . AreEqual ( HttpStatusCode . NotFound , response . StatusCode ) ;
2022-06-21 08:09:38 +02:00
Assert . AreEqual (
AngularJsonMediaTypeFormatter . XsrfPrefix + "{\"Message\":\"No variants flagged for saving\"}" , body ) ;
} ) ;
}
/// <summary>
/// Returns 404 if any of the posted properties dont actually exist
/// </summary>
[Test]
2023-09-12 14:16:27 +02:00
[LongRunning]
2022-06-21 08:09:38 +02:00
public async Task PostSave_Validate_Properties_Exist ( )
{
var localizationService = GetRequiredService < ILocalizationService > ( ) ;
// Add another language
localizationService . Save ( new LanguageBuilder ( )
. WithCultureInfo ( DkIso )
. WithIsDefault ( false )
. Build ( ) ) ;
var url = PrepareApiControllerUrl < ContentController > ( x = > x . PostSave ( null ) ) ;
var contentService = GetRequiredService < IContentService > ( ) ;
var contentTypeService = GetRequiredService < IContentTypeService > ( ) ;
var contentType = new ContentTypeBuilder ( )
. WithId ( 0 )
. AddPropertyType ( )
. WithAlias ( "title" )
. WithValueStorageType ( ValueStorageType . Integer )
. WithPropertyEditorAlias ( Constants . PropertyEditors . Aliases . TextBox )
. WithName ( "Title" )
. Done ( )
. WithContentVariation ( ContentVariation . Nothing )
. Build ( ) ;
contentTypeService . Save ( contentType ) ;
var content = new ContentBuilder ( )
. WithId ( 0 )
. WithName ( "Invariant" )
. WithContentType ( contentType )
. AddPropertyData ( )
. WithKeyValue ( "title" , "Cool invariant title" )
. Done ( )
. Build ( ) ;
contentService . SaveAndPublish ( content ) ;
var model = new ContentItemSaveBuilder ( )
. WithId ( content . Id )
. WithContentTypeAlias ( content . ContentType . Alias )
. AddVariant ( )
. AddProperty ( )
. WithId ( 2 )
. WithAlias ( "doesntexists" )
. WithValue ( "Whatever" )
. Done ( )
. Done ( )
. Build ( ) ;
// Act
2022-06-21 08:20:25 +02:00
var response =
await Client . PostAsync ( url , new MultipartFormDataContent { { new StringContent ( JsonConvert . SerializeObject ( model ) ) , "contentItem" } } ) ;
2022-06-21 08:09:38 +02:00
// Assert
var body = await response . Content . ReadAsStringAsync ( ) ;
body = body . TrimStart ( AngularJsonMediaTypeFormatter . XsrfPrefix ) ;
Assert . AreEqual ( HttpStatusCode . NotFound , response . StatusCode ) ;
}
2020-06-17 16:39:28 +02:00
2022-06-21 08:09:38 +02:00
[Test]
2023-09-12 14:16:27 +02:00
[LongRunning]
2022-06-21 08:09:38 +02:00
public async Task PostSave_Simple_Invariant ( )
{
var localizationService = GetRequiredService < ILocalizationService > ( ) ;
// Add another language
localizationService . Save ( new LanguageBuilder ( )
. WithCultureInfo ( DkIso )
. WithIsDefault ( false )
. Build ( ) ) ;
var url = PrepareApiControllerUrl < ContentController > ( x = > x . PostSave ( null ) ) ;
var contentService = GetRequiredService < IContentService > ( ) ;
var contentTypeService = GetRequiredService < IContentTypeService > ( ) ;
var contentType = new ContentTypeBuilder ( )
. WithId ( 0 )
. AddPropertyType ( )
. WithAlias ( "title" )
. WithValueStorageType ( ValueStorageType . Integer )
. WithPropertyEditorAlias ( Constants . PropertyEditors . Aliases . TextBox )
. WithName ( "Title" )
. Done ( )
. WithContentVariation ( ContentVariation . Nothing )
. Build ( ) ;
contentTypeService . Save ( contentType ) ;
var content = new ContentBuilder ( )
. WithId ( 0 )
. WithName ( "Invariant" )
. WithContentType ( contentType )
. AddPropertyData ( )
. WithKeyValue ( "title" , "Cool invariant title" )
. Done ( )
. Build ( ) ;
contentService . SaveAndPublish ( content ) ;
var model = new ContentItemSaveBuilder ( )
. WithContent ( content )
. Build ( ) ;
// Act
2022-06-21 08:20:25 +02:00
var response =
await Client . PostAsync ( url , new MultipartFormDataContent { { new StringContent ( JsonConvert . SerializeObject ( model ) ) , "contentItem" } } ) ;
2022-06-21 08:09:38 +02:00
// Assert
var body = await response . Content . ReadAsStringAsync ( ) ;
body = body . TrimStart ( AngularJsonMediaTypeFormatter . XsrfPrefix ) ;
Assert . Multiple ( ( ) = >
2020-06-17 16:39:28 +02:00
{
2022-06-21 08:09:38 +02:00
Assert . AreEqual ( HttpStatusCode . OK , response . StatusCode , body ) ;
var display = JsonConvert . DeserializeObject < ContentItemDisplay > ( body ) ;
Assert . AreEqual ( 1 , display . Variants . Count ( ) ) ;
} ) ;
}
[Test]
2023-09-12 14:16:27 +02:00
[LongRunning]
2022-06-21 08:09:38 +02:00
public async Task PostSave_Validate_Empty_Name ( )
{
var localizationService = GetRequiredService < ILocalizationService > ( ) ;
// Add another language
localizationService . Save ( new LanguageBuilder ( )
. WithCultureInfo ( DkIso )
. WithIsDefault ( false )
. Build ( ) ) ;
var url = PrepareApiControllerUrl < ContentController > ( x = > x . PostSave ( null ) ) ;
var contentService = GetRequiredService < IContentService > ( ) ;
var contentTypeService = GetRequiredService < IContentTypeService > ( ) ;
var contentType = new ContentTypeBuilder ( )
. WithId ( 0 )
. AddPropertyType ( )
. WithAlias ( "title" )
. WithValueStorageType ( ValueStorageType . Integer )
. WithPropertyEditorAlias ( Constants . PropertyEditors . Aliases . TextBox )
. WithName ( "Title" )
. Done ( )
. WithContentVariation ( ContentVariation . Nothing )
. Build ( ) ;
contentTypeService . Save ( contentType ) ;
var content = new ContentBuilder ( )
. WithId ( 0 )
. WithName ( "Invariant" )
. WithContentType ( contentType )
. AddPropertyData ( )
. WithKeyValue ( "title" , "Cool invariant title" )
. Done ( )
. Build ( ) ;
contentService . SaveAndPublish ( content ) ;
content . Name = null ; // Removes the name of one of the variants to force an error
var model = new ContentItemSaveBuilder ( )
. WithContent ( content )
. Build ( ) ;
// Act
2022-06-21 08:20:25 +02:00
var response =
await Client . PostAsync ( url , new MultipartFormDataContent { { new StringContent ( JsonConvert . SerializeObject ( model ) ) , "contentItem" } } ) ;
2022-06-21 08:09:38 +02:00
// Assert
var body = await response . Content . ReadAsStringAsync ( ) ;
body = body . TrimStart ( AngularJsonMediaTypeFormatter . XsrfPrefix ) ;
Assert . Multiple ( ( ) = >
2020-06-17 16:39:28 +02:00
{
2022-06-21 08:09:38 +02:00
Assert . AreEqual ( HttpStatusCode . BadRequest , response . StatusCode ) ;
var display = JsonConvert . DeserializeObject < ContentItemDisplay > ( body ) ;
Assert . AreEqual ( 1 , display . Errors . Count ( ) , string . Join ( "," , display . Errors ) ) ;
CollectionAssert . Contains ( display . Errors . Keys , "Variants[0].Name" ) ;
} ) ;
}
[Test]
2023-09-12 14:16:27 +02:00
[LongRunning]
2022-06-21 08:09:38 +02:00
public async Task PostSave_Validate_Variants_Empty_Name ( )
{
var localizationService = GetRequiredService < ILocalizationService > ( ) ;
// Add another language
localizationService . Save ( new LanguageBuilder ( )
. WithCultureInfo ( DkIso )
. WithIsDefault ( false )
. Build ( ) ) ;
var url = PrepareApiControllerUrl < ContentController > ( x = > x . PostSave ( null ) ) ;
var contentService = GetRequiredService < IContentService > ( ) ;
var contentTypeService = GetRequiredService < IContentTypeService > ( ) ;
var contentType = new ContentTypeBuilder ( )
. WithId ( 0 )
. AddPropertyType ( )
. WithAlias ( "title" )
. WithValueStorageType ( ValueStorageType . Integer )
. WithPropertyEditorAlias ( Constants . PropertyEditors . Aliases . TextBox )
. WithName ( "Title" )
. Done ( )
. WithContentVariation ( ContentVariation . Culture )
. Build ( ) ;
contentTypeService . Save ( contentType ) ;
var content = new ContentBuilder ( )
. WithId ( 0 )
. WithCultureName ( UsIso , "English" )
. WithCultureName ( DkIso , "Danish" )
. WithContentType ( contentType )
. AddPropertyData ( )
. WithKeyValue ( "title" , "Cool invariant title" )
. Done ( )
. Build ( ) ;
contentService . SaveAndPublish ( content ) ;
content . CultureInfos [ 0 ] . Name = null ; // Removes the name of one of the variants to force an error
var model = new ContentItemSaveBuilder ( )
. WithContent ( content )
. Build ( ) ;
// Act
2022-06-21 08:20:25 +02:00
var response =
await Client . PostAsync ( url , new MultipartFormDataContent { { new StringContent ( JsonConvert . SerializeObject ( model ) ) , "contentItem" } } ) ;
2022-06-21 08:09:38 +02:00
// Assert
var body = await response . Content . ReadAsStringAsync ( ) ;
body = body . TrimStart ( AngularJsonMediaTypeFormatter . XsrfPrefix ) ;
Assert . Multiple ( ( ) = >
2020-06-17 16:39:28 +02:00
{
2022-06-21 08:09:38 +02:00
Assert . AreEqual ( HttpStatusCode . BadRequest , response . StatusCode ) ;
var display = JsonConvert . DeserializeObject < ContentItemDisplay > ( body ) ;
Assert . AreEqual ( 2 , display . Errors . Count ( ) ) ;
CollectionAssert . Contains ( display . Errors . Keys , "Variants[0].Name" ) ;
CollectionAssert . Contains ( display . Errors . Keys , "_content_variant_en-US_null_" ) ;
} ) ;
}
[Test]
2023-09-12 14:16:27 +02:00
[LongRunning]
2022-06-21 08:09:38 +02:00
public async Task PostSave_Validates_Domains_Exist ( )
{
var localizationService = GetRequiredService < ILocalizationService > ( ) ;
localizationService . Save ( new LanguageBuilder ( )
. WithCultureInfo ( DkIso )
. WithIsDefault ( false )
. Build ( ) ) ;
var contentTypeService = GetRequiredService < IContentTypeService > ( ) ;
var contentType = new ContentTypeBuilder ( ) . WithContentVariation ( ContentVariation . Culture ) . Build ( ) ;
contentTypeService . Save ( contentType ) ;
var content = new ContentBuilder ( )
. WithId ( 1 )
. WithContentType ( contentType )
. WithCultureName ( UsIso , "Root" )
. WithCultureName ( DkIso , "Rod" )
. Build ( ) ;
var model = new ContentItemSaveBuilder ( )
. WithContent ( content )
. WithAction ( ContentSaveAction . PublishNew )
. Build ( ) ;
var url = PrepareApiControllerUrl < ContentController > ( x = > x . PostSave ( null ) ) ;
2022-06-21 08:20:25 +02:00
var response =
await Client . PostAsync ( url , new MultipartFormDataContent { { new StringContent ( JsonConvert . SerializeObject ( model ) ) , "contentItem" } } ) ;
2022-06-21 08:09:38 +02:00
var body = await response . Content . ReadAsStringAsync ( ) ;
body = body . TrimStart ( AngularJsonMediaTypeFormatter . XsrfPrefix ) ;
var display = JsonConvert . DeserializeObject < ContentItemDisplay > ( body ) ;
var localizedTextService = GetRequiredService < ILocalizedTextService > ( ) ;
var expectedMessage = localizedTextService . Localize ( "speechBubbles" , "publishWithNoDomains" ) ;
Assert . Multiple ( ( ) = >
2021-10-07 16:34:38 +02:00
{
2022-06-21 08:09:38 +02:00
Assert . IsNotNull ( display ) ;
Assert . AreEqual ( 1 , display . Notifications . Count ( x = > x . NotificationType = = NotificationStyle . Warning ) ) ;
2022-06-21 08:20:25 +02:00
Assert . AreEqual (
expectedMessage ,
display . Notifications . FirstOrDefault ( x = > x . NotificationType = = NotificationStyle . Warning ) ? . Message ) ;
2022-06-21 08:09:38 +02:00
} ) ;
}
[Test]
2023-09-12 14:16:27 +02:00
[LongRunning]
2022-06-21 08:09:38 +02:00
public async Task PostSave_Validates_All_Ancestor_Cultures_Are_Considered ( )
{
var sweIso = "sv-SE" ;
var localizationService = GetRequiredService < ILocalizationService > ( ) ;
//Create 2 new languages
localizationService . Save ( new LanguageBuilder ( )
. WithCultureInfo ( DkIso )
. WithIsDefault ( false )
. Build ( ) ) ;
localizationService . Save ( new LanguageBuilder ( )
. WithCultureInfo ( sweIso )
. WithIsDefault ( false )
. Build ( ) ) ;
var contentTypeService = GetRequiredService < IContentTypeService > ( ) ;
var contentType = new ContentTypeBuilder ( ) . WithContentVariation ( ContentVariation . Culture ) . Build ( ) ;
contentTypeService . Save ( contentType ) ;
var content = new ContentBuilder ( )
. WithoutIdentity ( )
. WithContentType ( contentType )
. WithCultureName ( UsIso , "Root" )
. Build ( ) ;
var contentService = GetRequiredService < IContentService > ( ) ;
contentService . SaveAndPublish ( content ) ;
var childContent = new ContentBuilder ( )
. WithoutIdentity ( )
. WithContentType ( contentType )
. WithParent ( content )
. WithCultureName ( DkIso , "Barn" )
. WithCultureName ( UsIso , "Child" )
. Build ( ) ;
contentService . SaveAndPublish ( childContent ) ;
var grandChildContent = new ContentBuilder ( )
. WithoutIdentity ( )
. WithContentType ( contentType )
. WithParent ( childContent )
. WithCultureName ( sweIso , "Bjarn" )
. Build ( ) ;
var model = new ContentItemSaveBuilder ( )
. WithContent ( grandChildContent )
. WithParentId ( childContent . Id )
. WithAction ( ContentSaveAction . PublishNew )
. Build ( ) ;
var enLanguage = localizationService . GetLanguageByIsoCode ( UsIso ) ;
var domainService = GetRequiredService < IDomainService > ( ) ;
2022-06-21 08:20:25 +02:00
var enDomain = new UmbracoDomain ( "/en" ) { RootContentId = content . Id , LanguageId = enLanguage . Id } ;
2022-06-21 08:09:38 +02:00
domainService . Save ( enDomain ) ;
var dkLanguage = localizationService . GetLanguageByIsoCode ( DkIso ) ;
2022-06-21 08:20:25 +02:00
var dkDomain = new UmbracoDomain ( "/dk" ) { RootContentId = childContent . Id , LanguageId = dkLanguage . Id } ;
2022-06-21 08:09:38 +02:00
domainService . Save ( dkDomain ) ;
var url = PrepareApiControllerUrl < ContentController > ( x = > x . PostSave ( null ) ) ;
var result = JsonConvert . SerializeObject ( model ) ;
2022-06-21 08:20:25 +02:00
var response =
await Client . PostAsync ( url , new MultipartFormDataContent { { new StringContent ( JsonConvert . SerializeObject ( model ) ) , "contentItem" } } ) ;
2022-06-21 08:09:38 +02:00
var body = await response . Content . ReadAsStringAsync ( ) ;
body = body . TrimStart ( AngularJsonMediaTypeFormatter . XsrfPrefix ) ;
var display = JsonConvert . DeserializeObject < ContentItemDisplay > ( body ) ;
var localizedTextService = GetRequiredService < ILocalizedTextService > ( ) ;
var expectedMessage =
2022-06-21 08:20:25 +02:00
localizedTextService . Localize ( "speechBubbles" , "publishWithMissingDomain" , new [ ] { "sv-SE" } ) ;
2022-06-21 08:09:38 +02:00
Assert . Multiple ( ( ) = >
2021-10-15 11:47:48 +02:00
{
2022-06-21 08:09:38 +02:00
Assert . NotNull ( display ) ;
Assert . AreEqual ( 1 , display . Notifications . Count ( x = > x . NotificationType = = NotificationStyle . Warning ) ) ;
2022-06-21 08:20:25 +02:00
Assert . AreEqual (
expectedMessage ,
display . Notifications . FirstOrDefault ( x = > x . NotificationType = = NotificationStyle . Warning ) ? . Message ) ;
2022-06-21 08:09:38 +02:00
} ) ;
}
[Test]
2023-09-12 14:16:27 +02:00
[LongRunning]
2022-06-21 08:09:38 +02:00
public async Task PostSave_Validates_All_Cultures_Has_Domains ( )
{
var localizationService = GetRequiredService < ILocalizationService > ( ) ;
localizationService . Save ( new LanguageBuilder ( )
. WithCultureInfo ( DkIso )
. WithIsDefault ( false )
. Build ( ) ) ;
var contentTypeService = GetRequiredService < IContentTypeService > ( ) ;
var contentType = new ContentTypeBuilder ( ) . WithContentVariation ( ContentVariation . Culture ) . Build ( ) ;
contentTypeService . Save ( contentType ) ;
var content = new ContentBuilder ( )
. WithoutIdentity ( )
. WithContentType ( contentType )
. WithCultureName ( UsIso , "Root" )
. WithCultureName ( DkIso , "Rod" )
. Build ( ) ;
var contentService = GetRequiredService < IContentService > ( ) ;
contentService . Save ( content ) ;
var model = new ContentItemSaveBuilder ( )
. WithContent ( content )
. WithAction ( ContentSaveAction . Publish )
. Build ( ) ;
var dkLanguage = localizationService . GetLanguageByIsoCode ( DkIso ) ;
var domainService = GetRequiredService < IDomainService > ( ) ;
2022-06-21 08:20:25 +02:00
var dkDomain = new UmbracoDomain ( "/" ) { RootContentId = content . Id , LanguageId = dkLanguage . Id } ;
2022-06-21 08:09:38 +02:00
domainService . Save ( dkDomain ) ;
var url = PrepareApiControllerUrl < ContentController > ( x = > x . PostSave ( null ) ) ;
2022-06-21 08:20:25 +02:00
var response =
await Client . PostAsync ( url , new MultipartFormDataContent { { new StringContent ( JsonConvert . SerializeObject ( model ) ) , "contentItem" } } ) ;
2022-06-21 08:09:38 +02:00
var body = await response . Content . ReadAsStringAsync ( ) ;
body = body . TrimStart ( AngularJsonMediaTypeFormatter . XsrfPrefix ) ;
var display = JsonConvert . DeserializeObject < ContentItemDisplay > ( body ) ;
var localizedTextService = GetRequiredService < ILocalizedTextService > ( ) ;
2022-06-21 08:20:25 +02:00
var expectedMessage = localizedTextService . Localize ( "speechBubbles" , "publishWithMissingDomain" , new [ ] { UsIso } ) ;
2022-06-21 08:09:38 +02:00
Assert . Multiple ( ( ) = >
2021-10-08 13:08:32 +02:00
{
2022-06-21 08:09:38 +02:00
Assert . NotNull ( display ) ;
Assert . AreEqual ( 1 , display . Notifications . Count ( x = > x . NotificationType = = NotificationStyle . Warning ) ) ;
2022-06-21 08:20:25 +02:00
Assert . AreEqual (
expectedMessage ,
display . Notifications . FirstOrDefault ( x = > x . NotificationType = = NotificationStyle . Warning ) ? . Message ) ;
2022-06-21 08:09:38 +02:00
} ) ;
}
[Test]
2023-09-12 14:16:27 +02:00
[LongRunning]
2022-06-21 08:09:38 +02:00
public async Task PostSave_Checks_Ancestors_For_Domains ( )
{
var localizationService = GetRequiredService < ILocalizationService > ( ) ;
localizationService . Save ( new LanguageBuilder ( )
. WithCultureInfo ( DkIso )
. WithIsDefault ( false )
. Build ( ) ) ;
var contentTypeService = GetRequiredService < IContentTypeService > ( ) ;
var contentType = new ContentTypeBuilder ( ) . WithContentVariation ( ContentVariation . Culture ) . Build ( ) ;
contentTypeService . Save ( contentType ) ;
var rootNode = new ContentBuilder ( )
. WithoutIdentity ( )
. WithContentType ( contentType )
. WithCultureName ( UsIso , "Root" )
. WithCultureName ( DkIso , "Rod" )
. Build ( ) ;
var contentService = GetRequiredService < IContentService > ( ) ;
contentService . SaveAndPublish ( rootNode ) ;
var childNode = new ContentBuilder ( )
. WithoutIdentity ( )
. WithParent ( rootNode )
. WithContentType ( contentType )
. WithCultureName ( DkIso , "Barn" )
. WithCultureName ( UsIso , "Child" )
. Build ( ) ;
contentService . SaveAndPublish ( childNode ) ;
var grandChild = new ContentBuilder ( )
. WithoutIdentity ( )
. WithParent ( childNode )
. WithContentType ( contentType )
. WithCultureName ( DkIso , "BarneBarn" )
. WithCultureName ( UsIso , "GrandChild" )
. Build ( ) ;
contentService . Save ( grandChild ) ;
var dkLanguage = localizationService . GetLanguageByIsoCode ( DkIso ) ;
var usLanguage = localizationService . GetLanguageByIsoCode ( UsIso ) ;
var domainService = GetRequiredService < IDomainService > ( ) ;
2022-06-21 08:20:25 +02:00
var dkDomain = new UmbracoDomain ( "/" ) { RootContentId = rootNode . Id , LanguageId = dkLanguage . Id } ;
2022-06-21 08:09:38 +02:00
2022-06-21 08:20:25 +02:00
var usDomain = new UmbracoDomain ( "/en" ) { RootContentId = childNode . Id , LanguageId = usLanguage . Id } ;
2022-06-21 08:09:38 +02:00
domainService . Save ( dkDomain ) ;
domainService . Save ( usDomain ) ;
var url = PrepareApiControllerUrl < ContentController > ( x = > x . PostSave ( null ) ) ;
var model = new ContentItemSaveBuilder ( )
. WithContent ( grandChild )
. WithAction ( ContentSaveAction . Publish )
. Build ( ) ;
2022-06-21 08:20:25 +02:00
var response =
await Client . PostAsync ( url , new MultipartFormDataContent { { new StringContent ( JsonConvert . SerializeObject ( model ) ) , "contentItem" } } ) ;
2022-06-21 08:09:38 +02:00
var body = await response . Content . ReadAsStringAsync ( ) ;
body = body . TrimStart ( AngularJsonMediaTypeFormatter . XsrfPrefix ) ;
var display = JsonConvert . DeserializeObject < ContentItemDisplay > ( body ) ;
Assert . Multiple ( ( ) = >
2021-10-08 14:52:22 +02:00
{
2022-06-21 08:09:38 +02:00
Assert . NotNull ( display ) ;
// Assert all is good, a success notification for each culture published and no warnings.
Assert . AreEqual ( 2 , display . Notifications . Count ( x = > x . NotificationType = = NotificationStyle . Success ) ) ;
Assert . AreEqual ( 0 , display . Notifications . Count ( x = > x . NotificationType = = NotificationStyle . Warning ) ) ;
} ) ;
2020-06-17 16:39:28 +02:00
}
2023-07-18 07:17:19 +00:00
[ TestCase (
@"<p><img alt src=""data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7""></p>" ,
false ) ]
[ TestCase (
@"<p><img src=""data:image/svg+xml;utf8,<svg viewBox=""0 0 70 74"" fill=""none"" xmlns=""http://www.w3.org/2000/svg""><rect width=""100%"" height=""100%"" fill=""black""/></svg>""></p>" ,
false ) ]
[ TestCase (
@"<p><img alt src=""/some/random/image.jpg""></p><p><img alt src=""data:image/jpg;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7""></p>" ,
false ) ]
[ TestCase (
@"<p><img alt src=""data:image/notallowedextension;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7""></p>" ,
true ) ]
2023-09-12 14:16:27 +02:00
[LongRunning]
2023-07-18 07:17:19 +00:00
public async Task PostSave_Simple_RichText_With_Base64 ( string html , bool shouldHaveDataUri )
{
var url = PrepareApiControllerUrl < ContentController > ( x = > x . PostSave ( null ) ) ;
var dataTypeService = GetRequiredService < IDataTypeService > ( ) ;
var contentService = GetRequiredService < IContentService > ( ) ;
var contentTypeService = GetRequiredService < IContentTypeService > ( ) ;
var dataType = new DataTypeBuilder ( )
. WithId ( 0 )
. WithoutIdentity ( )
. WithDatabaseType ( ValueStorageType . Ntext )
. AddEditor ( )
. WithAlias ( Constants . PropertyEditors . Aliases . TinyMce )
. Done ( )
. Build ( ) ;
dataTypeService . Save ( dataType ) ;
var contentType = new ContentTypeBuilder ( )
. WithId ( 0 )
. AddPropertyType ( )
. WithDataTypeId ( dataType . Id )
. WithAlias ( "richText" )
. WithName ( "Rich Text" )
. Done ( )
. WithContentVariation ( ContentVariation . Nothing )
. Build ( ) ;
contentTypeService . Save ( contentType ) ;
var content = new ContentBuilder ( )
. WithId ( 0 )
. WithName ( "Invariant" )
. WithContentType ( contentType )
. AddPropertyData ( )
. WithKeyValue ( "richText" , html )
. Done ( )
. Build ( ) ;
contentService . SaveAndPublish ( content ) ;
var model = new ContentItemSaveBuilder ( )
. WithContent ( content )
. Build ( ) ;
// Act
var response =
await Client . PostAsync ( url , new MultipartFormDataContent { { new StringContent ( JsonConvert . SerializeObject ( model ) ) , "contentItem" } } ) ;
// Assert
var body = await response . Content . ReadAsStringAsync ( ) ;
body = body . TrimStart ( AngularJsonMediaTypeFormatter . XsrfPrefix ) ;
Assert . Multiple ( ( ) = >
{
Assert . AreEqual ( HttpStatusCode . OK , response . StatusCode , body ) ;
var display = JsonConvert . DeserializeObject < ContentItemDisplay > ( body ) ;
var bodyText = display . Variants . FirstOrDefault ( ) ? . Tabs . FirstOrDefault ( ) ? . Properties
? . FirstOrDefault ( x = > x . Alias . Equals ( "richText" ) ) ? . Value ? . ToString ( ) ;
Assert . NotNull ( bodyText ) ;
var containsDataUri = bodyText . Contains ( "data:image" ) ;
if ( shouldHaveDataUri )
{
Assert . True ( containsDataUri , $"Data URIs were expected to be found in the body: {bodyText}" ) ;
} else {
Assert . False ( containsDataUri , $"Data URIs were not expected to be found in the body: {bodyText}" ) ;
}
} ) ;
}
2020-06-17 16:39:28 +02:00
}