2020-12-23 11:35:49 +01:00
// Copyright (c) Umbraco.
// See LICENSE for more details.
2020-06-17 16:39:28 +02:00
using System.Net ;
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 ;
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
{
2023-01-26 13:34:11 +01:00
var languageService = GetRequiredService < ILanguageService > ( ) ;
2022-06-21 08:09:38 +02:00
// Add another language
2023-03-21 12:41:20 +01:00
await languageService . CreateAsync (
new LanguageBuilder ( )
2022-06-21 08:09:38 +02:00
. WithCultureInfo ( DkIso )
. WithIsDefault ( false )
2023-03-21 12:41:20 +01:00
. Build ( ) ,
Constants . Security . SuperUserKey ) ;
2022-06-21 08:09:38 +02:00
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 ( ) ;
2023-11-22 12:52:08 +01:00
contentService . Save ( content ) ;
contentService . Publish ( content , Array . Empty < string > ( ) ) ;
2022-06-21 08:09:38 +02:00
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 ( )
{
2023-01-26 13:34:11 +01:00
var languageService = GetRequiredService < ILanguageService > ( ) ;
2022-06-21 08:09:38 +02:00
// Add another language
2023-03-21 12:41:20 +01:00
await languageService . CreateAsync (
new LanguageBuilder ( )
2022-06-21 08:09:38 +02:00
. WithCultureInfo ( DkIso )
. WithIsDefault ( false )
2023-03-21 12:41:20 +01:00
. Build ( ) ,
Constants . Security . SuperUserKey ) ;
2022-06-21 08:09:38 +02:00
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 ( ) ;
2023-11-22 12:52:08 +01:00
contentService . Save ( content ) ;
contentService . Publish ( content , Array . Empty < string > ( ) ) ;
2022-06-21 08:09:38 +02:00
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 ( )
{
2023-01-26 13:34:11 +01:00
var languageService = GetRequiredService < ILanguageService > ( ) ;
2022-06-21 08:09:38 +02:00
// Add another language
2023-03-21 12:41:20 +01:00
await languageService . CreateAsync (
new LanguageBuilder ( )
2022-06-21 08:09:38 +02:00
. WithCultureInfo ( DkIso )
. WithIsDefault ( false )
2023-03-21 12:41:20 +01:00
. Build ( ) ,
Constants . Security . SuperUserKey ) ;
2022-06-21 08:09:38 +02:00
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 ( ) ;
2023-11-22 12:52:08 +01:00
contentService . Save ( content ) ;
contentService . Publish ( content , Array . Empty < string > ( ) ) ;
2022-06-21 08:09:38 +02:00
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 ( )
{
2023-01-26 13:34:11 +01:00
var languageService = GetRequiredService < ILanguageService > ( ) ;
2022-06-21 08:09:38 +02:00
// Add another language
2023-03-21 12:41:20 +01:00
await languageService . CreateAsync (
new LanguageBuilder ( )
2022-06-21 08:09:38 +02:00
. WithCultureInfo ( DkIso )
. WithIsDefault ( false )
2023-03-21 12:41:20 +01:00
. Build ( ) ,
Constants . Security . SuperUserKey ) ;
2022-06-21 08:09:38 +02:00
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 ( ) ;
2023-11-22 12:52:08 +01:00
contentService . Save ( content ) ;
contentService . Publish ( content , Array . Empty < string > ( ) ) ;
2022-06-21 08:09:38 +02:00
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 ( )
{
2023-01-26 13:34:11 +01:00
var languageService = GetRequiredService < ILanguageService > ( ) ;
2022-06-21 08:09:38 +02:00
// Add another language
2023-03-21 12:41:20 +01:00
await languageService . CreateAsync (
new LanguageBuilder ( )
2022-06-21 08:09:38 +02:00
. WithCultureInfo ( DkIso )
. WithIsDefault ( false )
2023-03-21 12:41:20 +01:00
. Build ( ) ,
Constants . Security . SuperUserKey ) ;
2022-06-21 08:09:38 +02:00
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 ( ) ;
2023-11-22 12:52:08 +01:00
contentService . Save ( content ) ;
contentService . Publish ( content , Array . Empty < string > ( ) ) ;
2022-06-21 08:09:38 +02:00
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 ( )
{
2023-01-26 13:34:11 +01:00
var languageService = GetRequiredService < ILanguageService > ( ) ;
2022-06-21 08:09:38 +02:00
// Add another language
2023-03-21 12:41:20 +01:00
await languageService . CreateAsync (
new LanguageBuilder ( )
2022-06-21 08:09:38 +02:00
. WithCultureInfo ( DkIso )
. WithIsDefault ( false )
2023-03-21 12:41:20 +01:00
. Build ( ) ,
Constants . Security . SuperUserKey ) ;
2022-06-21 08:09:38 +02:00
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 ( ) ;
2023-11-22 12:52:08 +01:00
contentService . Save ( content ) ;
contentService . Publish ( content , content . AvailableCultures . ToArray ( ) ) ;
2022-06-21 08:09:38 +02:00
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_" ) ;
} ) ;
}
2024-02-01 14:28:47 +01:00
[Retry(5)] // TODO make this test non-flaky.
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_Domains_Exist ( )
{
2023-01-26 13:34:11 +01:00
var languageService = GetRequiredService < ILanguageService > ( ) ;
2023-03-21 12:41:20 +01:00
await languageService . CreateAsync (
new LanguageBuilder ( )
2022-06-21 08:09:38 +02:00
. WithCultureInfo ( DkIso )
. WithIsDefault ( false )
2023-03-21 12:41:20 +01:00
. Build ( ) ,
Constants . Security . SuperUserKey ) ;
2022-06-21 08:09:38 +02:00
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" ;
2023-01-26 13:34:11 +01:00
var languageService = GetRequiredService < ILanguageService > ( ) ;
2022-06-21 08:09:38 +02:00
//Create 2 new languages
2023-03-21 12:41:20 +01:00
await languageService . CreateAsync (
new LanguageBuilder ( )
2022-06-21 08:09:38 +02:00
. WithCultureInfo ( DkIso )
. WithIsDefault ( false )
2023-03-21 12:41:20 +01:00
. Build ( ) ,
Constants . Security . SuperUserKey ) ;
2022-06-21 08:09:38 +02:00
2023-03-21 12:41:20 +01:00
await languageService . CreateAsync (
new LanguageBuilder ( )
2022-06-21 08:09:38 +02:00
. WithCultureInfo ( sweIso )
. WithIsDefault ( false )
2023-03-21 12:41:20 +01:00
. Build ( ) ,
Constants . Security . SuperUserKey ) ;
2022-06-21 08:09:38 +02:00
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 > ( ) ;
2023-11-22 12:52:08 +01:00
contentService . Save ( content ) ;
contentService . Publish ( content , content . AvailableCultures . ToArray ( ) ) ;
2022-06-21 08:09:38 +02:00
var childContent = new ContentBuilder ( )
. WithoutIdentity ( )
. WithContentType ( contentType )
. WithParent ( content )
. WithCultureName ( DkIso , "Barn" )
. WithCultureName ( UsIso , "Child" )
. Build ( ) ;
2023-11-22 12:52:08 +01:00
contentService . Save ( childContent ) ;
contentService . Publish ( childContent , content . AvailableCultures . ToArray ( ) ) ;
2022-06-21 08:09:38 +02:00
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 ( ) ;
2023-01-26 13:34:11 +01:00
var enLanguage = await languageService . GetAsync ( UsIso ) ;
2023-03-15 10:28:23 +01:00
var dkLanguage = await languageService . GetAsync ( DkIso ) ;
2022-06-21 08:09:38 +02:00
var domainService = GetRequiredService < IDomainService > ( ) ;
2023-03-15 10:28:23 +01:00
await domainService . UpdateDomainsAsync (
content . Key ,
new DomainsUpdateModel
{
Domains = new [ ] { new DomainModel { DomainName = "/en" , IsoCode = enLanguage . IsoCode } }
} ) ;
await domainService . UpdateDomainsAsync (
childContent . Key ,
new DomainsUpdateModel
{
Domains = new [ ] { new DomainModel { DomainName = "/dk" , IsoCode = dkLanguage . IsoCode } }
} ) ;
2022-06-21 08:09:38 +02:00
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 ( )
{
2023-01-26 13:34:11 +01:00
var languageService = GetRequiredService < ILanguageService > ( ) ;
2023-03-21 12:41:20 +01:00
await languageService . CreateAsync (
new LanguageBuilder ( )
2022-06-21 08:09:38 +02:00
. WithCultureInfo ( DkIso )
. WithIsDefault ( false )
2023-03-21 12:41:20 +01:00
. Build ( ) ,
Constants . Security . SuperUserKey ) ;
2022-06-21 08:09:38 +02:00
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 ( ) ;
2023-01-26 13:34:11 +01:00
var dkLanguage = await languageService . GetAsync ( DkIso ) ;
2022-06-21 08:09:38 +02:00
var domainService = GetRequiredService < IDomainService > ( ) ;
2023-03-15 10:28:23 +01:00
await domainService . UpdateDomainsAsync (
content . Key ,
new DomainsUpdateModel
{
Domains = new [ ] { new DomainModel { DomainName = "/" , IsoCode = dkLanguage . IsoCode } }
} ) ;
2022-06-21 08:09:38 +02:00
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 ( )
{
2023-01-26 13:34:11 +01:00
var languageService = GetRequiredService < ILanguageService > ( ) ;
2023-03-21 12:41:20 +01:00
await languageService . CreateAsync (
new LanguageBuilder ( )
2022-06-21 08:09:38 +02:00
. WithCultureInfo ( DkIso )
. WithIsDefault ( false )
2023-03-21 12:41:20 +01:00
. Build ( ) ,
Constants . Security . SuperUserKey ) ;
2022-06-21 08:09:38 +02:00
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 > ( ) ;
2023-11-22 12:52:08 +01:00
contentService . Save ( rootNode ) ;
contentService . Publish ( rootNode , rootNode . AvailableCultures . ToArray ( ) ) ;
2022-06-21 08:09:38 +02:00
var childNode = new ContentBuilder ( )
. WithoutIdentity ( )
. WithParent ( rootNode )
. WithContentType ( contentType )
. WithCultureName ( DkIso , "Barn" )
. WithCultureName ( UsIso , "Child" )
. Build ( ) ;
2023-11-22 12:52:08 +01:00
contentService . Save ( childNode ) ;
contentService . Publish ( childNode , childNode . AvailableCultures . ToArray ( ) ) ;
2022-06-21 08:09:38 +02:00
var grandChild = new ContentBuilder ( )
. WithoutIdentity ( )
. WithParent ( childNode )
. WithContentType ( contentType )
. WithCultureName ( DkIso , "BarneBarn" )
. WithCultureName ( UsIso , "GrandChild" )
. Build ( ) ;
contentService . Save ( grandChild ) ;
2023-01-26 13:34:11 +01:00
var dkLanguage = await languageService . GetAsync ( DkIso ) ;
var usLanguage = await languageService . GetAsync ( UsIso ) ;
2022-06-21 08:09:38 +02:00
var domainService = GetRequiredService < IDomainService > ( ) ;
2023-03-15 10:28:23 +01:00
await domainService . UpdateDomainsAsync (
rootNode . Key ,
new DomainsUpdateModel
{
Domains = new [ ] { new DomainModel { DomainName = "/" , IsoCode = dkLanguage . IsoCode } }
} ) ;
await domainService . UpdateDomainsAsync (
childNode . Key ,
new DomainsUpdateModel
{
Domains = new [ ] { new DomainModel { DomainName = "/en" , IsoCode = usLanguage . IsoCode } }
} ) ;
2022-06-21 08:09:38 +02:00
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
2023-07-21 12:21:56 +02:00
// FIXME: I've commented out this tests, since it should be relevant for new backoffice
// This is because in new backoffice we use the temporary file service to handle drag'n'dropped images
// see RichTextEditorPastedImages.FindAndPersistPastedTempImagesAsync for more information.
// [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-20 13:31:05 +02:00
// [LongRunning]
2023-07-21 12:21:56 +02: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
}