2020-12-23 11:35:49 +01:00
// Copyright (c) Umbraco.
// See LICENSE for more details.
2020-12-09 22:43:49 +11:00
using System ;
2018-06-29 19:52:40 +02:00
using System.Collections.Generic ;
using System.Linq ;
2020-09-17 10:35:11 +02:00
using Microsoft.Extensions.Logging ;
2020-12-23 11:35:49 +01:00
using Microsoft.Extensions.Options ;
2021-04-20 12:17:11 +02:00
using Moq ;
2018-06-29 19:52:40 +02:00
using NUnit.Framework ;
2021-02-09 10:22:42 +01:00
using Umbraco.Cms.Core ;
using Umbraco.Cms.Core.Cache ;
2021-07-12 15:28:46 -06:00
using Umbraco.Cms.Core.Composing ;
2021-02-09 10:22:42 +01:00
using Umbraco.Cms.Core.Configuration.Models ;
2021-04-20 12:17:11 +02:00
using Umbraco.Cms.Core.Events ;
2021-02-09 10:22:42 +01:00
using Umbraco.Cms.Core.IO ;
using Umbraco.Cms.Core.Models ;
using Umbraco.Cms.Core.Persistence ;
using Umbraco.Cms.Core.Persistence.Querying ;
using Umbraco.Cms.Core.PropertyEditors ;
2021-02-15 11:41:12 +01:00
using Umbraco.Cms.Core.Scoping ;
2021-02-09 10:22:42 +01:00
using Umbraco.Cms.Core.Serialization ;
using Umbraco.Cms.Core.Services ;
2021-02-12 13:36:50 +01:00
using Umbraco.Cms.Infrastructure.Persistence ;
using Umbraco.Cms.Infrastructure.Persistence.Repositories.Implement ;
using Umbraco.Cms.Infrastructure.Persistence.SqlSyntax ;
2021-02-10 14:45:44 +01:00
using Umbraco.Cms.Tests.Common.Builders ;
using Umbraco.Cms.Tests.Common.Testing ;
2021-02-11 08:30:27 +01:00
using Umbraco.Cms.Tests.Integration.Testing ;
2021-02-09 11:26:22 +01:00
using Umbraco.Extensions ;
2021-02-09 10:22:42 +01:00
using Constants = Umbraco . Cms . Core . Constants ;
2018-06-29 19:52:40 +02:00
2021-02-11 08:30:27 +01:00
namespace Umbraco.Cms.Tests.Integration.Umbraco.Infrastructure.Persistence.Repositories
2018-06-29 19:52:40 +02:00
{
[TestFixture]
[UmbracoTest(Database = UmbracoTestOptions.Database.NewSchemaPerTest)]
2020-10-09 13:08:23 +02:00
public class DocumentRepositoryTest : UmbracoIntegrationTest
2018-06-29 19:52:40 +02:00
{
2020-10-09 13:08:23 +02:00
private ContentType _contentType ;
private Content _textpage ;
private Content _subpage ;
private Content _subpage2 ;
private Content _trashed ;
private IContentService ContentService = > GetRequiredService < IContentService > ( ) ;
2020-12-23 11:35:49 +01:00
2020-10-09 13:08:23 +02:00
private IContentTypeService ContentTypeService = > GetRequiredService < IContentTypeService > ( ) ;
2020-12-23 11:35:49 +01:00
2020-10-09 13:08:23 +02:00
private IFileService FileService = > GetRequiredService < IFileService > ( ) ;
2020-12-23 11:35:49 +01:00
2020-10-09 13:08:23 +02:00
private IDataTypeService DataTypeService = > GetRequiredService < IDataTypeService > ( ) ;
2020-12-23 11:35:49 +01:00
2021-04-27 09:52:17 +02:00
private FileSystems FileSystems = > GetRequiredService < FileSystems > ( ) ;
2020-12-23 11:35:49 +01:00
2020-11-17 20:27:10 +01:00
private IConfigurationEditorJsonSerializer ConfigurationEditorJsonSerializer = > GetRequiredService < IConfigurationEditorJsonSerializer > ( ) ;
2020-10-09 13:08:23 +02:00
[SetUp]
public void SetUpData ( )
2018-06-29 19:52:40 +02:00
{
CreateTestData ( ) ;
ContentRepositoryBase . ThrowOnWarning = true ;
}
2020-10-27 14:10:19 +01:00
[TearDown]
2020-12-23 11:35:49 +01:00
public void Teardown ( ) = > ContentRepositoryBase . ThrowOnWarning = false ;
2018-06-29 19:52:40 +02:00
2020-10-09 13:08:23 +02:00
public void CreateTestData ( )
{
2020-12-23 11:35:49 +01:00
Template template = TemplateBuilder . CreateTextPageTemplate ( ) ;
2020-10-09 13:08:23 +02:00
FileService . SaveTemplate ( template ) ;
2020-12-23 11:35:49 +01:00
// Create and Save ContentType "umbTextpage" -> (_contentType.Id)
_contentType = ContentTypeBuilder . CreateSimpleContentType ( "umbTextpage" , "Textpage" , defaultTemplateId : template . Id ) ;
2020-10-09 13:08:23 +02:00
_contentType . Key = new Guid ( "1D3A8E6E-2EA9-4CC1-B229-1AEE19821522" ) ;
ContentTypeService . Save ( _contentType ) ;
2020-12-23 11:35:49 +01:00
// Create and Save Content "Homepage" based on "umbTextpage" -> (_textpage.Id)
2020-10-09 13:08:23 +02:00
_textpage = ContentBuilder . CreateSimpleContent ( _contentType ) ;
_textpage . Key = new Guid ( "B58B3AD4-62C2-4E27-B1BE-837BD7C533E0" ) ;
ContentService . Save ( _textpage , 0 ) ;
2020-12-23 11:35:49 +01:00
// Create and Save Content "Text Page 1" based on "umbTextpage" -> (_subpage.Id)
2020-10-09 13:08:23 +02:00
_subpage = ContentBuilder . CreateSimpleContent ( _contentType , "Text Page 1" , _textpage . Id ) ;
_subpage . Key = new Guid ( "FF11402B-7E53-4654-81A7-462AC2108059" ) ;
ContentService . Save ( _subpage , 0 ) ;
2020-12-23 11:35:49 +01:00
// Create and Save Content "Text Page 1" based on "umbTextpage" -> (_subpage2.Id)
2020-10-09 13:08:23 +02:00
_subpage2 = ContentBuilder . CreateSimpleContent ( _contentType , "Text Page 2" , _textpage . Id ) ;
ContentService . Save ( _subpage2 , 0 ) ;
2020-12-23 11:35:49 +01:00
// Create and Save Content "Text Page Deleted" based on "umbTextpage" -> (_trashed.Id)
2020-10-09 13:08:23 +02:00
_trashed = ContentBuilder . CreateSimpleContent ( _contentType , "Text Page Deleted" , - 20 ) ;
_trashed . Trashed = true ;
ContentService . Save ( _trashed , 0 ) ;
}
2019-01-17 08:34:29 +01:00
private DocumentRepository CreateRepository ( IScopeAccessor scopeAccessor , out ContentTypeRepository contentTypeRepository , out DataTypeRepository dtdRepository , AppCaches appCaches = null )
2018-06-29 19:52:40 +02:00
{
2020-12-23 11:35:49 +01:00
appCaches ? ? = AppCaches ;
2018-06-29 19:52:40 +02:00
2020-12-23 11:35:49 +01:00
DocumentRepository ctRepository = CreateRepository ( scopeAccessor , out contentTypeRepository , out TemplateRepository tr ) ;
2021-07-12 15:28:46 -06:00
var editors = new PropertyEditorCollection ( new DataEditorCollection ( ( ) = > Enumerable . Empty < IDataEditor > ( ) ) ) ;
dtdRepository = new DataTypeRepository ( scopeAccessor , appCaches , editors , LoggerFactory . CreateLogger < DataTypeRepository > ( ) , LoggerFactory , ConfigurationEditorJsonSerializer ) ;
2018-06-29 19:52:40 +02:00
return ctRepository ;
}
2020-12-23 11:35:49 +01:00
private DocumentRepository CreateRepository ( IScopeAccessor scopeAccessor , out ContentTypeRepository contentTypeRepository , AppCaches appCaches = null ) = >
CreateRepository ( scopeAccessor , out contentTypeRepository , out TemplateRepository tr , appCaches ) ;
2018-06-29 19:52:40 +02:00
2019-01-17 08:34:29 +01:00
private DocumentRepository CreateRepository ( IScopeAccessor scopeAccessor , out ContentTypeRepository contentTypeRepository , out TemplateRepository templateRepository , AppCaches appCaches = null )
2018-06-29 19:52:40 +02:00
{
2020-12-23 11:35:49 +01:00
IOptions < GlobalSettings > globalSettings = Options . Create ( new GlobalSettings ( ) ) ;
2020-08-24 16:06:09 +02:00
2020-12-23 11:35:49 +01:00
appCaches ? ? = AppCaches ;
2018-06-29 19:52:40 +02:00
2021-11-03 13:05:43 +01:00
templateRepository = new TemplateRepository ( scopeAccessor , appCaches , LoggerFactory . CreateLogger < TemplateRepository > ( ) , FileSystems , IOHelper , ShortStringHelper , Mock . Of < IViewHelper > ( ) ) ;
2020-09-21 13:04:57 +02:00
var tagRepository = new TagRepository ( scopeAccessor , appCaches , LoggerFactory . CreateLogger < TagRepository > ( ) ) ;
2019-12-09 14:12:06 +01:00
var commonRepository = new ContentTypeCommonRepository ( scopeAccessor , templateRepository , appCaches , ShortStringHelper ) ;
2020-09-21 13:04:57 +02:00
var languageRepository = new LanguageRepository ( scopeAccessor , appCaches , LoggerFactory . CreateLogger < LanguageRepository > ( ) , globalSettings ) ;
contentTypeRepository = new ContentTypeRepository ( scopeAccessor , appCaches , LoggerFactory . CreateLogger < ContentTypeRepository > ( ) , commonRepository , languageRepository , ShortStringHelper ) ;
var relationTypeRepository = new RelationTypeRepository ( scopeAccessor , AppCaches . Disabled , LoggerFactory . CreateLogger < RelationTypeRepository > ( ) ) ;
2020-12-09 22:43:49 +11:00
var entityRepository = new EntityRepository ( scopeAccessor , AppCaches . Disabled ) ;
2020-09-21 13:04:57 +02:00
var relationRepository = new RelationRepository ( scopeAccessor , LoggerFactory . CreateLogger < RelationRepository > ( ) , relationTypeRepository , entityRepository ) ;
2021-07-12 15:28:46 -06:00
var propertyEditors = new PropertyEditorCollection ( new DataEditorCollection ( ( ) = > Enumerable . Empty < IDataEditor > ( ) ) ) ;
var dataValueReferences = new DataValueReferenceFactoryCollection ( ( ) = > Enumerable . Empty < IDataValueReferenceFactory > ( ) ) ;
2020-12-23 11:35:49 +01:00
var repository = new DocumentRepository (
scopeAccessor ,
appCaches ,
LoggerFactory . CreateLogger < DocumentRepository > ( ) ,
LoggerFactory ,
contentTypeRepository ,
templateRepository ,
tagRepository ,
languageRepository ,
relationRepository ,
relationTypeRepository ,
propertyEditors ,
dataValueReferences ,
DataTypeService ,
2021-04-20 12:17:11 +02:00
ConfigurationEditorJsonSerializer ,
Mock . Of < IEventAggregator > ( ) ) ;
2018-06-29 19:52:40 +02:00
return repository ;
}
[Test]
public void CacheActiveForIntsAndGuids ( )
{
2019-01-17 08:34:29 +01:00
var realCache = new AppCaches (
2020-03-19 08:53:18 +01:00
new ObjectCacheAppCache ( ) ,
2019-01-18 08:29:16 +01:00
new DictionaryAppCache ( ) ,
2020-03-19 08:53:18 +01:00
new IsolatedCaches ( t = > new ObjectCacheAppCache ( ) ) ) ;
2018-06-29 19:52:40 +02:00
2020-12-23 11:35:49 +01:00
IScopeProvider provider = ScopeProvider ;
using ( IScope scope = provider . CreateScope ( ) )
2018-06-29 19:52:40 +02:00
{
2020-12-23 11:35:49 +01:00
DocumentRepository repository = CreateRepository ( ( IScopeAccessor ) provider , out ContentTypeRepository contentTypeRepository , appCaches : realCache ) ;
2018-06-29 19:52:40 +02:00
2020-12-23 11:35:49 +01:00
IUmbracoDatabase udb = scope . Database ;
2018-06-29 19:52:40 +02:00
udb . EnableSqlCount = false ;
2020-12-23 11:35:49 +01:00
Template template = TemplateBuilder . CreateTextPageTemplate ( ) ;
2020-10-09 13:08:23 +02:00
FileService . SaveTemplate ( template ) ;
2020-12-23 11:35:49 +01:00
ContentType contentType = ContentTypeBuilder . CreateSimpleContentType ( "umbTextpage1" , "Textpage" , defaultTemplateId : template . Id ) ;
2020-10-09 13:08:23 +02:00
2018-06-29 19:52:40 +02:00
contentTypeRepository . Save ( contentType ) ;
2020-12-23 11:35:49 +01:00
Content content = ContentBuilder . CreateSimpleContent ( contentType ) ;
2018-06-29 19:52:40 +02:00
repository . Save ( content ) ;
udb . EnableSqlCount = true ;
2020-12-23 11:35:49 +01:00
// go get it, this should already be cached since the default repository key is the INT
2018-06-29 19:52:40 +02:00
repository . Get ( content . Id ) ;
Assert . AreEqual ( 0 , udb . SqlCount ) ;
2020-12-23 11:35:49 +01:00
// retrieve again, this should use cache
2018-06-29 19:52:40 +02:00
repository . Get ( content . Id ) ;
Assert . AreEqual ( 0 , udb . SqlCount ) ;
2020-12-23 11:35:49 +01:00
// reset counter
2018-06-29 19:52:40 +02:00
udb . EnableSqlCount = false ;
udb . EnableSqlCount = true ;
2020-12-23 11:35:49 +01:00
// now get by GUID, this won't be cached yet because the default repo key is not a GUID
2018-06-29 19:52:40 +02:00
repository . Get ( content . Key ) ;
2020-12-23 11:35:49 +01:00
int sqlCount = udb . SqlCount ;
2018-06-29 19:52:40 +02:00
Assert . Greater ( sqlCount , 0 ) ;
2020-12-23 11:35:49 +01:00
// retrieve again, this should use cache now
2018-06-29 19:52:40 +02:00
repository . Get ( content . Key ) ;
Assert . AreEqual ( sqlCount , udb . SqlCount ) ;
}
}
[Test]
public void CreateVersions ( )
{
2020-12-23 11:35:49 +01:00
IScopeProvider provider = ScopeProvider ;
using ( IScope scope = provider . CreateScope ( ) )
2018-06-29 19:52:40 +02:00
{
2020-12-23 11:35:49 +01:00
DocumentRepository repository = CreateRepository ( ( IScopeAccessor ) provider , out ContentTypeRepository contentTypeRepository , out DataTypeRepository _ ) ;
2018-06-29 19:52:40 +02:00
var versions = new List < int > ( ) ;
2020-12-23 11:35:49 +01:00
Template template = TemplateBuilder . CreateTextPageTemplate ( ) ;
2020-10-09 13:08:23 +02:00
FileService . SaveTemplate ( template ) ;
2020-12-23 11:35:49 +01:00
ContentType hasPropertiesContentType = ContentTypeBuilder . CreateSimpleContentType ( "umbTextpage1" , "Textpage" , defaultTemplateId : template . Id ) ;
2018-06-29 19:52:40 +02:00
2019-02-05 19:58:33 +01:00
contentTypeRepository . Save ( hasPropertiesContentType ) ;
2020-10-09 13:08:23 +02:00
IContent content1 = ContentBuilder . CreateSimpleContent ( hasPropertiesContentType ) ;
2018-06-29 19:52:40 +02:00
// save = create the initial version
2018-05-01 13:43:27 +10:00
repository . Save ( content1 ) ;
2018-06-29 19:52:40 +02:00
versions . Add ( content1 . VersionId ) ; // the first version
// publish = new edit version
content1 . SetValue ( "title" , "title" ) ;
2019-04-02 10:46:37 +02:00
content1 . PublishCulture ( CultureImpact . Invariant ) ;
2019-03-27 12:41:02 +11:00
content1 . PublishedState = PublishedState . Publishing ;
2018-05-01 13:43:27 +10:00
repository . Save ( content1 ) ;
2018-06-29 19:52:40 +02:00
versions . Add ( content1 . VersionId ) ; // NEW VERSION
// new edit version has been created
2020-12-23 11:35:49 +01:00
Assert . AreNotEqual ( versions [ ^ 2 ] , versions [ ^ 1 ] ) ;
2018-06-29 19:52:40 +02:00
Assert . IsTrue ( content1 . Published ) ;
Assert . AreEqual ( PublishedState . Published , ( ( Content ) content1 ) . PublishedState ) ;
2020-12-23 11:35:49 +01:00
Assert . AreEqual ( versions [ ^ 1 ] , repository . Get ( content1 . Id ) . VersionId ) ;
2018-06-29 19:52:40 +02:00
// misc checks
Assert . AreEqual ( true , scope . Database . ExecuteScalar < bool > ( $"SELECT published FROM {Constants.DatabaseSchema.Tables.Document} WHERE nodeId=@id" , new { id = content1 . Id } ) ) ;
// change something
// save = update the current (draft) version
content1 . Name = "name-1" ;
content1 . SetValue ( "title" , "title-1" ) ;
2018-05-01 13:43:27 +10:00
repository . Save ( content1 ) ;
2018-06-29 19:52:40 +02:00
versions . Add ( content1 . VersionId ) ; // the same version
// no new version has been created
2020-12-23 11:35:49 +01:00
Assert . AreEqual ( versions [ ^ 2 ] , versions [ ^ 1 ] ) ;
2018-06-29 19:52:40 +02:00
Assert . IsTrue ( content1 . Published ) ;
2020-12-23 11:35:49 +01:00
Assert . AreEqual ( versions [ ^ 1 ] , repository . Get ( content1 . Id ) . VersionId ) ;
2018-06-29 19:52:40 +02:00
// misc checks
Assert . AreEqual ( true , scope . Database . ExecuteScalar < bool > ( $"SELECT published FROM {Constants.DatabaseSchema.Tables.Document} WHERE nodeId=@id" , new { id = content1 . Id } ) ) ;
// unpublish = no impact on versions
( ( Content ) content1 ) . PublishedState = PublishedState . Unpublishing ;
2018-05-01 13:43:27 +10:00
repository . Save ( content1 ) ;
2018-06-29 19:52:40 +02:00
versions . Add ( content1 . VersionId ) ; // the same version
// no new version has been created
2020-12-23 11:35:49 +01:00
Assert . AreEqual ( versions [ ^ 2 ] , versions [ ^ 1 ] ) ;
2018-06-29 19:52:40 +02:00
Assert . IsFalse ( content1 . Published ) ;
Assert . AreEqual ( PublishedState . Unpublished , ( ( Content ) content1 ) . PublishedState ) ;
2020-12-23 11:35:49 +01:00
Assert . AreEqual ( versions [ ^ 1 ] , repository . Get ( content1 . Id ) . VersionId ) ;
2018-06-29 19:52:40 +02:00
// misc checks
Assert . AreEqual ( false , scope . Database . ExecuteScalar < bool > ( $"SELECT published FROM {Constants.DatabaseSchema.Tables.Document} WHERE nodeId=@id" , new { id = content1 . Id } ) ) ;
// change something
// save = update the current (draft) version
content1 . Name = "name-2" ;
content1 . SetValue ( "title" , "title-2" ) ;
2018-05-01 13:43:27 +10:00
repository . Save ( content1 ) ;
2018-06-29 19:52:40 +02:00
versions . Add ( content1 . VersionId ) ; // the same version
// no new version has been created
2020-12-23 11:35:49 +01:00
Assert . AreEqual ( versions [ ^ 2 ] , versions [ ^ 1 ] ) ;
Assert . AreEqual ( versions [ ^ 1 ] , repository . Get ( content1 . Id ) . VersionId ) ;
2018-06-29 19:52:40 +02:00
// misc checks
Assert . AreEqual ( false , scope . Database . ExecuteScalar < bool > ( $"SELECT published FROM {Constants.DatabaseSchema.Tables.Document} WHERE nodeId=@id" , new { id = content1 . Id } ) ) ;
// publish = version
2019-04-02 10:46:37 +02:00
content1 . PublishCulture ( CultureImpact . Invariant ) ;
2019-03-27 12:41:02 +11:00
content1 . PublishedState = PublishedState . Publishing ;
2018-05-01 13:43:27 +10:00
repository . Save ( content1 ) ;
2018-06-29 19:52:40 +02:00
versions . Add ( content1 . VersionId ) ; // NEW VERSION
// new version has been created
2020-12-23 11:35:49 +01:00
Assert . AreNotEqual ( versions [ ^ 2 ] , versions [ ^ 1 ] ) ;
2018-06-29 19:52:40 +02:00
Assert . IsTrue ( content1 . Published ) ;
Assert . AreEqual ( PublishedState . Published , ( ( Content ) content1 ) . PublishedState ) ;
2020-12-23 11:35:49 +01:00
Assert . AreEqual ( versions [ ^ 1 ] , repository . Get ( content1 . Id ) . VersionId ) ;
2018-06-29 19:52:40 +02:00
// misc checks
Assert . AreEqual ( true , scope . Database . ExecuteScalar < bool > ( $"SELECT published FROM {Constants.DatabaseSchema.Tables.Document} WHERE nodeId=@id" , new { id = content1 . Id } ) ) ;
// change something
// save = update the current (draft) version
content1 . Name = "name-3" ;
content1 . SetValue ( "title" , "title-3" ) ;
2020-12-23 11:35:49 +01:00
//// Thread.Sleep(2000); // force date change
2018-06-29 19:52:40 +02:00
2018-05-01 13:43:27 +10:00
repository . Save ( content1 ) ;
2018-06-29 19:52:40 +02:00
versions . Add ( content1 . VersionId ) ; // the same version
// no new version has been created
2020-12-23 11:35:49 +01:00
Assert . AreEqual ( versions [ ^ 2 ] , versions [ ^ 1 ] ) ;
Assert . AreEqual ( versions [ ^ 1 ] , repository . Get ( content1 . Id ) . VersionId ) ;
2018-06-29 19:52:40 +02:00
// misc checks
Assert . AreEqual ( true , scope . Database . ExecuteScalar < bool > ( $"SELECT published FROM {Constants.DatabaseSchema.Tables.Document} WHERE nodeId=@id" , new { id = content1 . Id } ) ) ;
// publish = new version
content1 . Name = "name-4" ;
content1 . SetValue ( "title" , "title-4" ) ;
2019-04-02 10:46:37 +02:00
content1 . PublishCulture ( CultureImpact . Invariant ) ;
2019-03-27 12:41:02 +11:00
content1 . PublishedState = PublishedState . Publishing ;
2018-05-01 13:43:27 +10:00
repository . Save ( content1 ) ;
2018-06-29 19:52:40 +02:00
versions . Add ( content1 . VersionId ) ; // NEW VERSION
// a new version has been created
2020-12-23 11:35:49 +01:00
Assert . AreNotEqual ( versions [ ^ 2 ] , versions [ ^ 1 ] ) ;
2018-06-29 19:52:40 +02:00
Assert . IsTrue ( content1 . Published ) ;
Assert . AreEqual ( PublishedState . Published , ( ( Content ) content1 ) . PublishedState ) ;
2020-12-23 11:35:49 +01:00
Assert . AreEqual ( versions [ ^ 1 ] , repository . Get ( content1 . Id ) . VersionId ) ;
2018-06-29 19:52:40 +02:00
// misc checks
Assert . AreEqual ( true , scope . Database . ExecuteScalar < bool > ( $"SELECT published FROM {Constants.DatabaseSchema.Tables.Document} WHERE nodeId=@id" , new { id = content1 . Id } ) ) ;
// all versions
2020-12-23 11:35:49 +01:00
IContent [ ] allVersions = repository . GetAllVersions ( content1 . Id ) . ToArray ( ) ;
2018-06-29 19:52:40 +02:00
Console . WriteLine ( ) ;
2020-12-23 11:35:49 +01:00
foreach ( int v in versions )
{
2018-06-29 19:52:40 +02:00
Console . WriteLine ( v ) ;
2020-12-23 11:35:49 +01:00
}
2018-06-29 19:52:40 +02:00
Console . WriteLine ( ) ;
2020-12-23 11:35:49 +01:00
foreach ( IContent v in allVersions )
2018-06-29 19:52:40 +02:00
{
var c = ( Content ) v ;
Console . WriteLine ( $"{c.Id} {c.VersionId} {(c.Published ? " + " : " - ")}pub pk={c.VersionId} ppk={c.PublishedVersionId} name=\"{c.Name}\" pname=\"{c.PublishName}\"" ) ;
}
// get older version
2020-12-23 11:35:49 +01:00
IContent content = repository . GetVersion ( versions [ ^ 4 ] ) ;
2018-06-29 19:52:40 +02:00
Assert . AreNotEqual ( 0 , content . VersionId ) ;
2020-12-23 11:35:49 +01:00
Assert . AreEqual ( versions [ ^ 4 ] , content . VersionId ) ;
2018-06-29 19:52:40 +02:00
Assert . AreEqual ( "name-4" , content1 . Name ) ;
Assert . AreEqual ( "title-4" , content1 . GetValue ( "title" ) ) ;
Assert . AreEqual ( "name-2" , content . Name ) ;
Assert . AreEqual ( "title-2" , content . GetValue ( "title" ) ) ;
// get all versions - most recent first
allVersions = repository . GetAllVersions ( content1 . Id ) . ToArray ( ) ;
2020-12-23 11:35:49 +01:00
int [ ] expVersions = versions . Distinct ( ) . Reverse ( ) . ToArray ( ) ;
2018-06-29 19:52:40 +02:00
Assert . AreEqual ( expVersions . Length , allVersions . Length ) ;
2020-12-23 11:35:49 +01:00
for ( int i = 0 ; i < expVersions . Length ; i + + )
{
2018-06-29 19:52:40 +02:00
Assert . AreEqual ( expVersions [ i ] , allVersions [ i ] . VersionId ) ;
2020-12-23 11:35:49 +01:00
}
2018-06-29 19:52:40 +02:00
}
}
/// <summary>
/// This tests the regression issue of U4-9438
/// </summary>
/// <remarks>
/// The problem was the iteration of the property data in VersionableRepositoryBase when a content item
/// in the list actually doesn't have any property types, it would still skip over a property row.
/// To test, we have 3 content items, the first has properties, the second doesn't and the third does.
/// </remarks>
[Test]
public void PropertyDataAssignedCorrectly ( )
{
2020-12-23 11:35:49 +01:00
IScopeProvider provider = ScopeProvider ;
using ( IScope scope = provider . CreateScope ( ) )
2018-06-29 19:52:40 +02:00
{
2020-12-23 11:35:49 +01:00
Template template = TemplateBuilder . CreateTextPageTemplate ( ) ;
2020-10-09 13:08:23 +02:00
FileService . SaveTemplate ( template ) ;
2020-12-23 11:35:49 +01:00
DocumentRepository repository = CreateRepository ( ( IScopeAccessor ) provider , out ContentTypeRepository contentTypeRepository , out DataTypeRepository _ ) ;
2018-06-29 19:52:40 +02:00
2020-12-23 11:35:49 +01:00
ContentType emptyContentType = ContentTypeBuilder . CreateBasicContentType ( ) ;
ContentType hasPropertiesContentType = ContentTypeBuilder . CreateSimpleContentType ( "umbTextpage1" , "Textpage" , defaultTemplateId : template . Id ) ;
2019-01-03 09:27:52 +01:00
contentTypeRepository . Save ( emptyContentType ) ;
contentTypeRepository . Save ( hasPropertiesContentType ) ;
2020-12-23 11:35:49 +01:00
Content content1 = ContentBuilder . CreateSimpleContent ( hasPropertiesContentType ) ;
Content content2 = ContentBuilder . CreateBasicContent ( emptyContentType ) ;
Content content3 = ContentBuilder . CreateSimpleContent ( hasPropertiesContentType ) ;
2019-01-03 09:27:52 +01:00
2018-06-29 19:52:40 +02:00
repository . Save ( content1 ) ;
repository . Save ( content2 ) ;
2018-05-01 13:43:27 +10:00
repository . Save ( content3 ) ;
// this will cause the GetPropertyCollection to execute and we need to ensure that
// all of the properties and property types are all correct
2020-12-23 11:35:49 +01:00
IContent [ ] result = repository . GetMany ( content1 . Id , content2 . Id , content3 . Id ) . ToArray ( ) ;
IContent n1 = result [ 0 ] ;
IContent n2 = result [ 1 ] ;
IContent n3 = result [ 2 ] ;
2018-06-29 19:52:40 +02:00
Assert . AreEqual ( content1 . Id , n1 . Id ) ;
Assert . AreEqual ( content2 . Id , n2 . Id ) ;
Assert . AreEqual ( content3 . Id , n3 . Id ) ;
// compare everything including properties and their values
// this ensures that they have been properly retrieved
TestHelper . AssertPropertyValuesAreEqual ( content1 , n1 ) ;
TestHelper . AssertPropertyValuesAreEqual ( content2 , n2 ) ;
TestHelper . AssertPropertyValuesAreEqual ( content3 , n3 ) ;
}
}
2020-12-23 11:35:49 +01:00
//// /// <summary>
//// /// This test ensures that when property values using special database fields are saved, the actual data in the
//// /// object being stored is also transformed in the same way as the data being stored in the database is.
//// /// Before you would see that ex: a decimal value being saved as 100 or "100", would be that exact value in the
//// /// object, but the value saved to the database was actually 100.000000.
//// /// When querying the database for the value again - the value would then differ from what is in the object.
//// /// This caused inconsistencies between saving+publishing and simply saving and then publishing, due to the former
//// /// sending the non-transformed data directly on to publishing.
//// /// </summary>
//// [Test]
//// public void PropertyValuesWithSpecialTypes()
//// {
//// var provider = ScopeProvider;
//// using (var scope = provider.CreateScope())
//// {
//// var repository = CreateRepository((IScopeAccessor)provider, out var contentTypeRepository, out DataTypeRepository dataTypeDefinitionRepository);
////
//// var editor = new DecimalPropertyEditor(LoggerFactory, DataTypeService, LocalizationService, LocalizedTextService, ShortStringHelper);
//// var dtd = new DataType(editor) { Name = "test", DatabaseType = ValueStorageType.Decimal };
//// dataTypeDefinitionRepository.Save(dtd);
////
//// const string decimalPropertyAlias = "decimalProperty";
//// const string intPropertyAlias = "intProperty";
//// const string dateTimePropertyAlias = "datetimeProperty";
//// var dateValue = new DateTime(2016, 1, 6);
////
//// var propertyTypeCollection = new PropertyTypeCollection(true,
//// new List<PropertyType>
//// {
//// MockedPropertyTypes.CreateDecimalProperty(decimalPropertyAlias, "Decimal property", dtd.Id),
//// MockedPropertyTypes.CreateIntegerProperty(intPropertyAlias, "Integer property"),
//// MockedPropertyTypes.CreateDateTimeProperty(dateTimePropertyAlias, "DateTime property")
//// });
//// var contentType = ContentTypeBuilder.CreateSimpleContentType("umbTextpage1", "Textpage", propertyTypeCollection);
//// contentTypeRepository.Save(contentType);
////
//// // int and decimal values are passed in as strings as they would be from the backoffice UI
//// var textpage = ContentBuilder.CreateSimpleContentWithSpecialDatabaseTypes(contentType, "test@umbraco.org", -1, "100", "150", dateValue);
////
//// repository.Save(textpage);
//// scope.Complete();
////
//// Assert.That(contentType.HasIdentity, Is.True);
//// Assert.That(textpage.HasIdentity, Is.True);
////
//// var persistedTextpage = repository.Get(textpage.Id);
//// Assert.That(persistedTextpage.Name, Is.EqualTo(textpage.Name));
//// Assert.AreEqual(100m, persistedTextpage.GetValue(decimalPropertyAlias));
//// Assert.AreEqual(persistedTextpage.GetValue(decimalPropertyAlias), textpage.GetValue(decimalPropertyAlias));
//// Assert.AreEqual(150, persistedTextpage.GetValue(intPropertyAlias));
//// Assert.AreEqual(persistedTextpage.GetValue(intPropertyAlias), textpage.GetValue(intPropertyAlias));
//// Assert.AreEqual(dateValue, persistedTextpage.GetValue(dateTimePropertyAlias));
//// Assert.AreEqual(persistedTextpage.GetValue(dateTimePropertyAlias), textpage.GetValue(dateTimePropertyAlias));
//// }
//// }
2018-06-29 19:52:40 +02:00
[Test]
public void SaveContent ( )
{
2020-12-23 11:35:49 +01:00
IScopeProvider provider = ScopeProvider ;
using ( IScope scope = provider . CreateScope ( ) )
2018-06-29 19:52:40 +02:00
{
2020-12-23 11:35:49 +01:00
Template template = TemplateBuilder . CreateTextPageTemplate ( ) ;
2020-10-09 13:08:23 +02:00
FileService . SaveTemplate ( template ) ;
2020-12-23 11:35:49 +01:00
DocumentRepository repository = CreateRepository ( ( IScopeAccessor ) provider , out ContentTypeRepository contentTypeRepository ) ;
ContentType contentType = ContentTypeBuilder . CreateSimpleContentType ( "umbTextpage2" , "Textpage" , defaultTemplateId : template . Id ) ;
2019-02-05 19:58:33 +01:00
contentTypeRepository . Save ( contentType ) ;
2020-10-09 13:08:23 +02:00
IContent textpage = ContentBuilder . CreateSimpleContent ( contentType ) ;
2018-06-29 19:52:40 +02:00
repository . Save ( textpage ) ;
scope . Complete ( ) ;
Assert . That ( contentType . HasIdentity , Is . True ) ;
Assert . That ( textpage . HasIdentity , Is . True ) ;
}
2018-06-01 15:20:16 +10:00
}
2018-06-29 19:52:40 +02:00
[Test]
public void SaveContentWithDefaultTemplate ( )
{
2020-12-23 11:35:49 +01:00
IScopeProvider provider = ScopeProvider ;
using ( IScope scope = provider . CreateScope ( ) )
2018-06-29 19:52:40 +02:00
{
2020-12-23 11:35:49 +01:00
DocumentRepository repository = CreateRepository ( ( IScopeAccessor ) provider , out ContentTypeRepository contentTypeRepository , out TemplateRepository templateRepository ) ;
2018-06-29 19:52:40 +02:00
2019-12-09 14:12:06 +01:00
var template = new Template ( ShortStringHelper , "hello" , "hello" ) ;
2018-05-01 13:43:27 +10:00
templateRepository . Save ( template ) ;
2020-12-23 11:35:49 +01:00
ContentType contentType = ContentTypeBuilder . CreateSimpleContentType ( "umbTextpage2" , "Textpage" ) ;
2018-06-29 19:52:40 +02:00
contentType . AllowedTemplates = Enumerable . Empty < ITemplate > ( ) ; // because CreateSimpleContentType assigns one already
contentType . SetDefaultTemplate ( template ) ;
contentTypeRepository . Save ( contentType ) ;
2019-01-03 09:27:52 +01:00
2020-12-23 11:35:49 +01:00
Content textpage = ContentBuilder . CreateSimpleContent ( contentType ) ;
2018-05-01 13:43:27 +10:00
repository . Save ( textpage ) ;
2020-12-23 11:35:49 +01:00
IContent fetched = repository . Get ( textpage . Id ) ;
2018-06-29 19:52:40 +02:00
2018-11-08 16:46:12 +00:00
Assert . True ( textpage . TemplateId . HasValue ) ;
Assert . NotZero ( textpage . TemplateId . Value ) ;
2018-11-08 13:24:34 +00:00
Assert . AreEqual ( textpage . TemplateId , contentType . DefaultTemplate . Id ) ;
2018-06-29 19:52:40 +02:00
scope . Complete ( ) ;
2020-12-23 11:35:49 +01:00
TestHelper . AssertPropertyValuesAreEqual ( textpage , fetched ) ;
2018-06-29 19:52:40 +02:00
}
}
2020-12-23 11:35:49 +01:00
// Covers issue U4-2791 and U4-2607
2018-06-29 19:52:40 +02:00
[Test]
public void SaveContentWithAtSignInName ( )
{
// Arrange
2020-12-23 11:35:49 +01:00
IScopeProvider provider = ScopeProvider ;
using ( IScope scope = provider . CreateScope ( ) )
2018-06-29 19:52:40 +02:00
{
2020-12-23 11:35:49 +01:00
Template template = TemplateBuilder . CreateTextPageTemplate ( ) ;
2020-10-09 13:08:23 +02:00
FileService . SaveTemplate ( template ) ;
2020-12-23 11:35:49 +01:00
DocumentRepository repository = CreateRepository ( ( IScopeAccessor ) provider , out ContentTypeRepository contentTypeRepository ) ;
ContentType contentType = ContentTypeBuilder . CreateSimpleContentType ( "umbTextpage1" , "Textpage" , defaultTemplateId : template . Id ) ;
2018-05-01 13:43:27 +10:00
contentTypeRepository . Save ( contentType ) ;
2020-12-23 11:35:49 +01:00
Content textpage = ContentBuilder . CreateSimpleContent ( contentType , "test@umbraco.org" ) ;
Content anotherTextpage = ContentBuilder . CreateSimpleContent ( contentType , "@lightgiants" ) ;
2018-06-29 19:52:40 +02:00
repository . Save ( textpage ) ;
2018-05-01 13:43:27 +10:00
repository . Save ( anotherTextpage ) ;
2018-06-29 19:52:40 +02:00
Assert . That ( contentType . HasIdentity , Is . True ) ;
Assert . That ( textpage . HasIdentity , Is . True ) ;
2020-12-23 11:35:49 +01:00
IContent content = repository . Get ( textpage . Id ) ;
2018-06-29 19:52:40 +02:00
Assert . That ( content . Name , Is . EqualTo ( textpage . Name ) ) ;
2020-12-23 11:35:49 +01:00
IContent content2 = repository . Get ( anotherTextpage . Id ) ;
2018-06-29 19:52:40 +02:00
Assert . That ( content2 . Name , Is . EqualTo ( anotherTextpage . Name ) ) ;
scope . Complete ( ) ;
}
}
[Test]
public void SaveContentMultiple ( )
{
2020-12-23 11:35:49 +01:00
IScopeProvider provider = ScopeProvider ;
using ( IScope scope = provider . CreateScope ( ) )
2018-06-29 19:52:40 +02:00
{
2020-12-23 11:35:49 +01:00
Template template = TemplateBuilder . CreateTextPageTemplate ( ) ;
2020-10-09 13:08:23 +02:00
FileService . SaveTemplate ( template ) ;
2020-12-23 11:35:49 +01:00
DocumentRepository repository = CreateRepository ( ( IScopeAccessor ) provider , out ContentTypeRepository contentTypeRepository ) ;
ContentType contentType = ContentTypeBuilder . CreateSimpleContentType ( "umbTextpage1" , "Textpage" , defaultTemplateId : template . Id ) ;
2019-02-05 19:58:33 +01:00
contentTypeRepository . Save ( contentType ) ;
2020-12-23 11:35:49 +01:00
Content textpage = ContentBuilder . CreateSimpleContent ( contentType ) ;
2018-06-29 19:52:40 +02:00
2018-05-01 13:43:27 +10:00
repository . Save ( textpage ) ;
2020-12-23 11:35:49 +01:00
Content subpage = ContentBuilder . CreateSimpleContent ( contentType , "Text Page 1" , textpage . Id ) ;
2018-05-01 13:43:27 +10:00
repository . Save ( subpage ) ;
2018-06-29 19:52:40 +02:00
Assert . That ( contentType . HasIdentity , Is . True ) ;
Assert . That ( textpage . HasIdentity , Is . True ) ;
Assert . That ( subpage . HasIdentity , Is . True ) ;
Assert . That ( textpage . Id , Is . EqualTo ( subpage . ParentId ) ) ;
}
}
[Test]
public void GetContentIsNotDirty ( )
{
2020-12-23 11:35:49 +01:00
IScopeProvider provider = ScopeProvider ;
using ( IScope scope = provider . CreateScope ( ) )
2018-06-29 19:52:40 +02:00
{
2020-12-23 11:35:49 +01:00
DocumentRepository repository = CreateRepository ( ( IScopeAccessor ) provider , out _ ) ;
2018-06-29 19:52:40 +02:00
2020-12-23 11:35:49 +01:00
IContent content = repository . Get ( _subpage2 . Id ) ;
bool dirty = ( ( Content ) content ) . IsDirty ( ) ;
2018-06-29 19:52:40 +02:00
Assert . That ( dirty , Is . False ) ;
}
}
[Test]
public void UpdateContent ( )
{
2020-12-23 11:35:49 +01:00
IScopeProvider provider = ScopeProvider ;
using ( IScope scope = provider . CreateScope ( ) )
2018-06-29 19:52:40 +02:00
{
2020-12-23 11:35:49 +01:00
DocumentRepository repository = CreateRepository ( ( IScopeAccessor ) provider , out _ ) ;
2018-06-29 19:52:40 +02:00
2020-12-23 11:35:49 +01:00
IContent content = repository . Get ( _subpage . Id ) ;
2018-06-29 19:52:40 +02:00
content . Name = "About 2" ;
2018-05-01 13:43:27 +10:00
repository . Save ( content ) ;
2020-12-23 11:35:49 +01:00
IContent updatedContent = repository . Get ( _subpage . Id ) ;
2018-06-29 19:52:40 +02:00
Assert . AreEqual ( content . Id , updatedContent . Id ) ;
Assert . AreEqual ( content . Name , updatedContent . Name ) ;
Assert . AreEqual ( content . VersionId , updatedContent . VersionId ) ;
Assert . AreEqual ( content . GetValue ( "title" ) , "Welcome to our Home page" ) ;
content . SetValue ( "title" , "toot" ) ;
2018-05-01 13:43:27 +10:00
repository . Save ( content ) ;
2020-10-09 13:08:23 +02:00
updatedContent = repository . Get ( _subpage . Id ) ;
2018-06-29 19:52:40 +02:00
Assert . AreEqual ( "toot" , updatedContent . GetValue ( "title" ) ) ;
Assert . AreEqual ( content . VersionId , updatedContent . VersionId ) ;
}
}
[Test]
public void UpdateContentWithNullTemplate ( )
{
2020-12-23 11:35:49 +01:00
IScopeProvider provider = ScopeProvider ;
using ( IScope scope = provider . CreateScope ( ) )
2018-06-29 19:52:40 +02:00
{
2020-12-23 11:35:49 +01:00
DocumentRepository repository = CreateRepository ( ( IScopeAccessor ) provider , out _ ) ;
2018-06-29 19:52:40 +02:00
2020-12-23 11:35:49 +01:00
IContent content = repository . Get ( _subpage . Id ) ;
2018-11-13 16:20:11 +00:00
content . TemplateId = null ;
2018-05-01 13:43:27 +10:00
repository . Save ( content ) ;
2020-12-23 11:35:49 +01:00
IContent updatedContent = repository . Get ( _subpage . Id ) ;
2018-06-29 19:52:40 +02:00
2018-11-08 16:46:12 +00:00
Assert . False ( updatedContent . TemplateId . HasValue ) ;
2018-06-29 19:52:40 +02:00
}
}
[Test]
public void DeleteContent ( )
{
2020-12-23 11:35:49 +01:00
IScopeProvider provider = ScopeProvider ;
using ( IScope scope = provider . CreateScope ( ) )
2018-06-29 19:52:40 +02:00
{
2020-12-23 11:35:49 +01:00
DocumentRepository repository = CreateRepository ( ( IScopeAccessor ) provider , out ContentTypeRepository contentTypeRepository ) ;
IContentType contentType = contentTypeRepository . Get ( _contentType . Id ) ;
var content = new Content ( "Textpage 2 Child Node" , _trashed . Id , contentType )
{
CreatorId = 0 ,
WriterId = 0
} ;
2018-06-29 19:52:40 +02:00
2018-05-01 13:43:27 +10:00
repository . Save ( content ) ;
2020-12-23 11:35:49 +01:00
int id = content . Id ;
2018-06-29 19:52:40 +02:00
2018-05-01 13:43:27 +10:00
repository . Delete ( content ) ;
2020-12-23 11:35:49 +01:00
IContent content1 = repository . Get ( id ) ;
2018-06-29 19:52:40 +02:00
Assert . IsNull ( content1 ) ;
}
}
[Test]
public void GetContent ( )
{
2020-12-23 11:35:49 +01:00
IScopeProvider provider = ScopeProvider ;
using ( IScope scope = provider . CreateScope ( ) )
2018-06-29 19:52:40 +02:00
{
2020-12-23 11:35:49 +01:00
DocumentRepository repository = CreateRepository ( ( IScopeAccessor ) provider , out _ ) ;
IContent content = repository . Get ( _subpage2 . Id ) ;
2018-06-29 19:52:40 +02:00
2020-10-09 13:08:23 +02:00
Assert . AreEqual ( _subpage2 . Id , content . Id ) ;
2018-06-29 19:52:40 +02:00
Assert . That ( content . CreateDate , Is . GreaterThan ( DateTime . MinValue ) ) ;
Assert . That ( content . UpdateDate , Is . GreaterThan ( DateTime . MinValue ) ) ;
Assert . AreNotEqual ( 0 , content . ParentId ) ;
Assert . AreEqual ( "Text Page 2" , content . Name ) ;
Assert . AreNotEqual ( 0 , content . VersionId ) ;
2020-10-09 13:08:23 +02:00
Assert . AreEqual ( _contentType . Id , content . ContentTypeId ) ;
2018-06-29 19:52:40 +02:00
Assert . That ( content . Path , Is . Not . Empty ) ;
Assert . That ( content . Properties . Any ( ) , Is . True ) ;
}
}
[Test]
public void QueryContent ( )
{
2020-12-23 11:35:49 +01:00
IScopeProvider provider = ScopeProvider ;
using ( IScope scope = provider . CreateScope ( ) )
2018-06-29 19:52:40 +02:00
{
2020-12-23 11:35:49 +01:00
DocumentRepository repository = CreateRepository ( ( IScopeAccessor ) provider , out _ ) ;
2018-06-29 19:52:40 +02:00
2020-12-23 11:35:49 +01:00
IQuery < IContent > query = scope . SqlContext . Query < IContent > ( ) . Where ( x = > x . Level = = 2 ) ;
IEnumerable < IContent > result = repository . Get ( query ) ;
2018-06-29 19:52:40 +02:00
Assert . GreaterOrEqual ( 2 , result . Count ( ) ) ;
}
}
[Test]
public void GetAllContentManyVersions ( )
{
IContent [ ] result ;
2020-12-23 11:35:49 +01:00
IScopeProvider provider = ScopeProvider ;
using ( IScope scope = provider . CreateScope ( ) )
2018-06-29 19:52:40 +02:00
{
2020-12-23 11:35:49 +01:00
DocumentRepository repository = CreateRepository ( ( IScopeAccessor ) provider , out _ ) ;
2018-06-29 19:52:40 +02:00
result = repository . GetMany ( ) . ToArray ( ) ;
// save them all
2020-12-23 11:35:49 +01:00
foreach ( IContent content in result )
2018-06-29 19:52:40 +02:00
{
content . SetValue ( "title" , content . GetValue < string > ( "title" ) + "x" ) ;
repository . Save ( content ) ;
2018-05-01 13:43:27 +10:00
}
// publish them all
2020-12-23 11:35:49 +01:00
foreach ( IContent content in result )
2018-06-29 19:52:40 +02:00
{
2019-04-02 10:46:37 +02:00
content . PublishCulture ( CultureImpact . Invariant ) ;
2018-06-29 19:52:40 +02:00
repository . Save ( content ) ;
2018-05-01 13:43:27 +10:00
}
2018-06-29 19:52:40 +02:00
scope . Complete ( ) ;
}
// get them all again
2020-12-23 11:35:49 +01:00
using ( IScope scope = provider . CreateScope ( ) )
2018-06-29 19:52:40 +02:00
{
2020-12-23 11:35:49 +01:00
DocumentRepository repository = CreateRepository ( ( IScopeAccessor ) provider , out _ ) ;
IContent [ ] result2 = repository . GetMany ( ) . ToArray ( ) ;
2018-06-29 19:52:40 +02:00
Assert . AreEqual ( result . Length , result2 . Length ) ;
}
}
[Test]
2018-07-17 17:20:40 +02:00
public void AliasRegexTest ( )
2018-06-29 19:52:40 +02:00
{
2021-03-05 15:36:27 +01:00
System . Text . RegularExpressions . Regex regex = new SqlServerSyntaxProvider ( Options . Create ( new GlobalSettings ( ) ) ) . AliasRegex ;
2018-06-29 19:52:40 +02:00
Assert . AreEqual ( @"(\[\w+]\.\[\w+])\s+AS\s+(\[\w+])" , regex . ToString ( ) ) ;
const string sql = "SELECT [table].[column1] AS [alias1], [table].[column2] AS [alias2] FROM [table];" ;
2020-12-23 11:35:49 +01:00
System . Text . RegularExpressions . MatchCollection matches = regex . Matches ( sql ) ;
2018-06-29 19:52:40 +02:00
Assert . AreEqual ( 2 , matches . Count ) ;
Assert . AreEqual ( "[table].[column1]" , matches [ 0 ] . Groups [ 1 ] . Value ) ;
Assert . AreEqual ( "[alias1]" , matches [ 0 ] . Groups [ 2 ] . Value ) ;
Assert . AreEqual ( "[table].[column2]" , matches [ 1 ] . Groups [ 1 ] . Value ) ;
Assert . AreEqual ( "[alias2]" , matches [ 1 ] . Groups [ 2 ] . Value ) ;
}
[Test]
public void GetPagedResultsByQuery_With_Variant_Names ( )
2018-05-01 13:30:25 +10:00
{
2020-12-23 11:35:49 +01:00
// One invariant content type named "umbInvariantTextPage"
Template template = TemplateBuilder . CreateTextPageTemplate ( ) ;
2020-10-09 13:08:23 +02:00
FileService . SaveTemplate ( template ) ;
2020-12-23 11:35:49 +01:00
ContentType invariantCt = ContentTypeBuilder . CreateSimpleContentType ( "umbInvariantTextpage" , "Invariant Textpage" , defaultTemplateId : template . Id ) ;
2018-06-20 14:18:57 +02:00
invariantCt . Variations = ContentVariation . Nothing ;
2020-12-23 11:35:49 +01:00
foreach ( IPropertyType p in invariantCt . PropertyTypes )
{
p . Variations = ContentVariation . Nothing ;
}
2020-10-09 13:08:23 +02:00
ContentTypeService . Save ( invariantCt ) ;
2018-06-29 19:52:40 +02:00
2020-12-23 11:35:49 +01:00
// One variant (by culture) content type named "umbVariantTextPage"
2018-06-20 14:18:57 +02:00
// with properties, every 2nd one being variant (by culture), the other being invariant
2021-07-12 15:28:46 -06:00
ContentType variantCt = ContentTypeBuilder . CreateSimpleContentType ( "umbVariantTextpage" , "Variant Textpage" , defaultTemplateId : template . Id ) ;
2018-06-20 14:18:57 +02:00
variantCt . Variations = ContentVariation . Culture ;
2018-05-07 08:26:10 +02:00
var propTypes = variantCt . PropertyTypes . ToList ( ) ;
2020-12-23 11:35:49 +01:00
for ( int i = 0 ; i < propTypes . Count ; i + + )
2018-05-01 13:43:27 +10:00
{
2020-12-23 11:35:49 +01:00
IPropertyType p = propTypes [ i ] ;
2018-06-20 14:18:57 +02:00
p . Variations = i % 2 = = 0 ? ContentVariation . Culture : ContentVariation . Nothing ;
2018-05-01 13:43:27 +10:00
}
2020-10-09 13:08:23 +02:00
ContentTypeService . Save ( variantCt ) ;
2018-05-01 13:30:25 +10:00
2018-05-07 08:26:10 +02:00
invariantCt . AllowedContentTypes = new [ ] { new ContentTypeSort ( invariantCt . Id , 0 ) , new ContentTypeSort ( variantCt . Id , 1 ) } ;
2020-10-09 13:08:23 +02:00
ContentTypeService . Save ( invariantCt ) ;
2018-05-01 13:30:25 +10:00
2020-12-23 11:35:49 +01:00
// Create content
Content root = ContentBuilder . CreateSimpleContent ( invariantCt ) ;
2020-10-09 13:08:23 +02:00
ContentService . Save ( root ) ;
2018-05-01 13:30:25 +10:00
2018-06-20 14:18:57 +02:00
var children = new List < IContent > ( ) ;
2020-12-23 11:35:49 +01:00
for ( int i = 0 ; i < 25 ; i + + )
2018-05-01 13:30:25 +10:00
{
2020-12-23 11:35:49 +01:00
bool isInvariant = i % 2 = = 0 ;
string name = ( isInvariant ? "INV" : "VAR" ) + "_" + Guid . NewGuid ( ) ;
string culture = isInvariant ? null : "en-US" ;
2018-05-01 13:43:27 +10:00
2020-12-23 11:35:49 +01:00
Content child = ContentBuilder . CreateSimpleContent (
2018-05-07 08:26:10 +02:00
isInvariant ? invariantCt : variantCt ,
2020-12-23 11:35:49 +01:00
name ,
root ,
2018-05-01 13:43:27 +10:00
culture ,
setPropertyValues : isInvariant ) ;
if ( ! isInvariant )
{
2020-12-23 11:35:49 +01:00
// manually set the property values since we have mixed variant/invariant property types
2018-05-01 13:43:27 +10:00
child . SetValue ( "title" , name + " Subpage" , culture : culture ) ;
2020-12-23 11:35:49 +01:00
child . SetValue ( "bodyText" , "This is a subpage" , culture : null ) ; // this one is invariant
2018-05-01 13:43:27 +10:00
child . SetValue ( "author" , "John Doe" , culture : culture ) ;
}
2018-05-01 13:30:25 +10:00
2020-10-09 13:08:23 +02:00
ContentService . Save ( child ) ;
2018-06-20 14:18:57 +02:00
children . Add ( child ) ;
2018-05-01 13:30:25 +10:00
}
2018-06-29 19:52:40 +02:00
2020-12-23 11:35:49 +01:00
IContent child1 = children [ 1 ] ;
2018-06-20 14:18:57 +02:00
Assert . IsTrue ( child1 . ContentType . VariesByCulture ( ) ) ;
Assert . IsTrue ( child1 . Name . StartsWith ( "VAR" ) ) ;
Assert . IsTrue ( child1 . GetCultureName ( "en-US" ) . StartsWith ( "VAR" ) ) ;
2020-12-23 11:35:49 +01:00
IScopeProvider provider = ScopeProvider ;
using ( IScope scope = provider . CreateScope ( ) )
2018-06-29 19:52:40 +02:00
{
2020-12-23 11:35:49 +01:00
DocumentRepository repository = CreateRepository ( ( IScopeAccessor ) provider , out _ ) ;
2018-06-29 19:52:40 +02:00
2020-12-23 11:35:49 +01:00
IContent child = repository . Get ( children [ 1 ] . Id ) ; // 1 is variant
2018-06-20 14:18:57 +02:00
Assert . IsTrue ( child . ContentType . VariesByCulture ( ) ) ;
Assert . IsTrue ( child . Name . StartsWith ( "VAR" ) ) ;
Assert . IsTrue ( child . GetCultureName ( "en-US" ) . StartsWith ( "VAR" ) ) ;
2018-06-29 19:52:40 +02:00
try
{
scope . Database . AsUmbracoDatabase ( ) . EnableSqlTrace = true ;
scope . Database . AsUmbracoDatabase ( ) . EnableSqlCount = true ;
2020-12-23 11:35:49 +01:00
IQuery < IContent > query = scope . SqlContext . Query < IContent > ( ) . Where ( x = > x . ParentId = = root . Id ) ;
IEnumerable < IContent > result = repository . GetPage ( query , 0 , 20 , out long totalRecords , null , Ordering . By ( "UpdateDate" ) ) ;
2018-05-01 13:30:25 +10:00
Assert . AreEqual ( 25 , totalRecords ) ;
2020-12-23 11:35:49 +01:00
foreach ( IContent r in result )
2018-05-01 13:30:25 +10:00
{
2020-12-23 11:35:49 +01:00
bool isInvariant = r . ContentType . Alias = = "umbInvariantTextpage" ;
string name = isInvariant ? r . Name : r . CultureInfos [ "en-US" ] . Name ;
string namePrefix = isInvariant ? "INV" : "VAR" ;
2018-05-01 13:30:25 +10:00
2020-12-23 11:35:49 +01:00
// ensure the correct name (invariant vs variant) is in the result
2018-05-01 13:30:25 +10:00
Assert . IsTrue ( name . StartsWith ( namePrefix ) ) ;
2020-12-23 11:35:49 +01:00
foreach ( IProperty p in r . Properties )
2018-05-01 13:30:25 +10:00
{
2020-12-23 11:35:49 +01:00
// ensure there is a value for the correct variant/invariant property
object value = p . GetValue ( p . PropertyType . Variations . VariesByNothing ( ) ? null : "en-US" ) ;
2018-05-01 13:30:25 +10:00
Assert . IsNotNull ( value ) ;
}
2018-06-29 19:52:40 +02:00
}
}
finally
{
scope . Database . AsUmbracoDatabase ( ) . EnableSqlTrace = false ;
scope . Database . AsUmbracoDatabase ( ) . EnableSqlCount = false ;
}
}
}
[Test]
public void GetPagedResultsByQuery_CustomPropertySort ( )
{
2020-12-23 11:35:49 +01:00
IScopeProvider provider = ScopeProvider ;
using ( IScope scope = provider . CreateScope ( ) )
2018-06-29 19:52:40 +02:00
{
2020-12-23 11:35:49 +01:00
DocumentRepository repository = CreateRepository ( ( IScopeAccessor ) provider , out _ ) ;
2018-06-29 19:52:40 +02:00
2020-12-23 11:35:49 +01:00
IQuery < IContent > query = scope . SqlContext . Query < IContent > ( ) . Where ( x = > x . Name . Contains ( "Text" ) ) ;
2018-06-29 19:52:40 +02:00
try
{
scope . Database . AsUmbracoDatabase ( ) . EnableSqlTrace = true ;
scope . Database . AsUmbracoDatabase ( ) . EnableSqlCount = true ;
2020-12-23 11:35:49 +01:00
IEnumerable < IContent > result = repository . GetPage ( query , 0 , 2 , out long totalRecords , null , Ordering . By ( "title" , isCustomField : true ) ) ;
2018-06-29 19:52:40 +02:00
Assert . AreEqual ( 3 , totalRecords ) ;
Assert . AreEqual ( 2 , result . Count ( ) ) ;
2018-09-18 11:53:33 +02:00
result = repository . GetPage ( query , 1 , 2 , out totalRecords , null , Ordering . By ( "title" , isCustomField : true ) ) ;
2018-06-29 19:52:40 +02:00
Assert . AreEqual ( 1 , result . Count ( ) ) ;
}
finally
{
scope . Database . AsUmbracoDatabase ( ) . EnableSqlTrace = false ;
scope . Database . AsUmbracoDatabase ( ) . EnableSqlCount = false ;
}
}
}
[Test]
public void GetPagedResultsByQuery_FirstPage ( )
{
2020-12-23 11:35:49 +01:00
IScopeProvider provider = ScopeProvider ;
using ( IScope scope = provider . CreateScope ( ) )
2018-06-29 19:52:40 +02:00
{
2020-12-23 11:35:49 +01:00
DocumentRepository repository = CreateRepository ( ( IScopeAccessor ) provider , out _ ) ;
2018-06-29 19:52:40 +02:00
2020-12-23 11:35:49 +01:00
IQuery < IContent > query = scope . SqlContext . Query < IContent > ( ) . Where ( x = > x . Level = = 2 ) ;
2018-06-29 19:52:40 +02:00
try
{
scope . Database . AsUmbracoDatabase ( ) . EnableSqlTrace = true ;
scope . Database . AsUmbracoDatabase ( ) . EnableSqlCount = true ;
2020-12-23 11:35:49 +01:00
IEnumerable < IContent > result = repository . GetPage ( query , 0 , 1 , out long totalRecords , null , Ordering . By ( "Name" ) ) ;
2018-06-29 19:52:40 +02:00
Assert . That ( totalRecords , Is . GreaterThanOrEqualTo ( 2 ) ) ;
Assert . That ( result . Count ( ) , Is . EqualTo ( 1 ) ) ;
Assert . That ( result . First ( ) . Name , Is . EqualTo ( "Text Page 1" ) ) ;
}
finally
{
scope . Database . AsUmbracoDatabase ( ) . EnableSqlTrace = false ;
scope . Database . AsUmbracoDatabase ( ) . EnableSqlCount = false ;
}
}
}
[Test]
public void GetPagedResultsByQuery_SecondPage ( )
{
2020-12-23 11:35:49 +01:00
IScopeProvider provider = ScopeProvider ;
using ( IScope scope = provider . CreateScope ( ) )
2018-06-29 19:52:40 +02:00
{
2020-12-23 11:35:49 +01:00
DocumentRepository repository = CreateRepository ( ( IScopeAccessor ) provider , out _ ) ;
2018-06-29 19:52:40 +02:00
2020-12-23 11:35:49 +01:00
IQuery < IContent > query = scope . SqlContext . Query < IContent > ( ) . Where ( x = > x . Level = = 2 ) ;
IEnumerable < IContent > result = repository . GetPage ( query , 1 , 1 , out long totalRecords , null , Ordering . By ( "Name" ) ) ;
2018-06-29 19:52:40 +02:00
Assert . That ( totalRecords , Is . GreaterThanOrEqualTo ( 2 ) ) ;
Assert . That ( result . Count ( ) , Is . EqualTo ( 1 ) ) ;
Assert . That ( result . First ( ) . Name , Is . EqualTo ( "Text Page 2" ) ) ;
}
}
[Test]
public void GetPagedResultsByQuery_SinglePage ( )
{
2020-12-23 11:35:49 +01:00
IScopeProvider provider = ScopeProvider ;
using ( IScope scope = provider . CreateScope ( ) )
2018-06-29 19:52:40 +02:00
{
2020-12-23 11:35:49 +01:00
DocumentRepository repository = CreateRepository ( ( IScopeAccessor ) provider , out _ ) ;
2018-06-29 19:52:40 +02:00
2020-12-23 11:35:49 +01:00
IQuery < IContent > query = scope . SqlContext . Query < IContent > ( ) . Where ( x = > x . Level = = 2 ) ;
IEnumerable < IContent > result = repository . GetPage ( query , 0 , 2 , out long totalRecords , null , Ordering . By ( "Name" ) ) ;
2018-06-29 19:52:40 +02:00
Assert . That ( totalRecords , Is . GreaterThanOrEqualTo ( 2 ) ) ;
Assert . That ( result . Count ( ) , Is . EqualTo ( 2 ) ) ;
Assert . That ( result . First ( ) . Name , Is . EqualTo ( "Text Page 1" ) ) ;
}
}
[Test]
public void GetPagedResultsByQuery_DescendingOrder ( )
{
2020-12-23 11:35:49 +01:00
IScopeProvider provider = ScopeProvider ;
using ( IScope scope = provider . CreateScope ( ) )
2018-06-29 19:52:40 +02:00
{
2020-12-23 11:35:49 +01:00
DocumentRepository repository = CreateRepository ( ( IScopeAccessor ) provider , out _ ) ;
2018-06-29 19:52:40 +02:00
2020-12-23 11:35:49 +01:00
IQuery < IContent > query = scope . SqlContext . Query < IContent > ( ) . Where ( x = > x . Level = = 2 ) ;
IEnumerable < IContent > result = repository . GetPage ( query , 0 , 1 , out long totalRecords , null , Ordering . By ( "Name" , Direction . Descending ) ) ;
2018-06-29 19:52:40 +02:00
Assert . That ( totalRecords , Is . GreaterThanOrEqualTo ( 2 ) ) ;
Assert . That ( result . Count ( ) , Is . EqualTo ( 1 ) ) ;
Assert . That ( result . First ( ) . Name , Is . EqualTo ( "Text Page 2" ) ) ;
}
}
[Test]
public void GetPagedResultsByQuery_FilterMatchingSome ( )
{
2020-12-23 11:35:49 +01:00
IScopeProvider provider = ScopeProvider ;
using ( IScope scope = provider . CreateScope ( ) )
2018-06-29 19:52:40 +02:00
{
2020-12-23 11:35:49 +01:00
DocumentRepository repository = CreateRepository ( ( IScopeAccessor ) provider , out _ ) ;
2018-06-29 19:52:40 +02:00
2020-12-23 11:35:49 +01:00
IQuery < IContent > query = scope . SqlContext . Query < IContent > ( ) . Where ( x = > x . Level = = 2 ) ;
2018-06-29 19:52:40 +02:00
2020-12-23 11:35:49 +01:00
IQuery < IContent > filterQuery = scope . SqlContext . Query < IContent > ( ) . Where ( x = > x . Name . Contains ( "Page 2" ) ) ;
IEnumerable < IContent > result = repository . GetPage ( query , 0 , 1 , out long totalRecords , filterQuery , Ordering . By ( "Name" ) ) ;
2018-06-29 19:52:40 +02:00
Assert . That ( totalRecords , Is . EqualTo ( 1 ) ) ;
Assert . That ( result . Count ( ) , Is . EqualTo ( 1 ) ) ;
Assert . That ( result . First ( ) . Name , Is . EqualTo ( "Text Page 2" ) ) ;
}
}
[Test]
public void GetPagedResultsByQuery_FilterMatchingAll ( )
{
2020-12-23 11:35:49 +01:00
IScopeProvider provider = ScopeProvider ;
using ( IScope scope = provider . CreateScope ( ) )
2018-06-29 19:52:40 +02:00
{
2020-12-23 11:35:49 +01:00
DocumentRepository repository = CreateRepository ( ( IScopeAccessor ) provider , out _ ) ;
2018-06-29 19:52:40 +02:00
2020-12-23 11:35:49 +01:00
IQuery < IContent > query = scope . SqlContext . Query < IContent > ( ) . Where ( x = > x . Level = = 2 ) ;
2018-06-29 19:52:40 +02:00
2020-12-23 11:35:49 +01:00
IQuery < IContent > filterQuery = scope . SqlContext . Query < IContent > ( ) . Where ( x = > x . Name . Contains ( "text" ) ) ;
IEnumerable < IContent > result = repository . GetPage ( query , 0 , 1 , out long totalRecords , filterQuery , Ordering . By ( "Name" ) ) ;
2018-06-29 19:52:40 +02:00
Assert . That ( totalRecords , Is . EqualTo ( 2 ) ) ;
Assert . That ( result . Count ( ) , Is . EqualTo ( 1 ) ) ;
Assert . That ( result . First ( ) . Name , Is . EqualTo ( "Text Page 1" ) ) ;
}
}
[Test]
public void GetAllContentByIds ( )
{
2020-12-23 11:35:49 +01:00
IScopeProvider provider = ScopeProvider ;
using ( IScope scope = provider . CreateScope ( ) )
2018-06-29 19:52:40 +02:00
{
2020-12-23 11:35:49 +01:00
DocumentRepository repository = CreateRepository ( ( IScopeAccessor ) provider , out _ ) ;
2018-06-29 19:52:40 +02:00
2020-12-23 11:35:49 +01:00
IEnumerable < IContent > contents = repository . GetMany ( _subpage . Id , _subpage2 . Id ) ;
2018-06-29 19:52:40 +02:00
Assert . That ( contents , Is . Not . Null ) ;
Assert . That ( contents . Any ( ) , Is . True ) ;
Assert . That ( contents . Count ( ) , Is . EqualTo ( 2 ) ) ;
}
}
[Test]
public void GetAllContent ( )
{
2020-12-23 11:35:49 +01:00
IScopeProvider provider = ScopeProvider ;
using ( IScope scope = provider . CreateScope ( ) )
2018-06-29 19:52:40 +02:00
{
2020-12-23 11:35:49 +01:00
DocumentRepository repository = CreateRepository ( ( IScopeAccessor ) provider , out _ ) ;
2018-06-29 19:52:40 +02:00
2020-12-23 11:35:49 +01:00
IEnumerable < IContent > contents = repository . GetMany ( ) ;
2018-06-29 19:52:40 +02:00
Assert . That ( contents , Is . Not . Null ) ;
Assert . That ( contents . Any ( ) , Is . True ) ;
Assert . That ( contents . Count ( ) , Is . GreaterThanOrEqualTo ( 4 ) ) ;
contents = repository . GetMany ( contents . Select ( x = > x . Id ) . ToArray ( ) ) ;
Assert . That ( contents , Is . Not . Null ) ;
Assert . That ( contents . Any ( ) , Is . True ) ;
Assert . That ( contents . Count ( ) , Is . GreaterThanOrEqualTo ( 4 ) ) ;
contents = ( ( IReadRepository < Guid , IContent > ) repository ) . GetMany ( contents . Select ( x = > x . Key ) . ToArray ( ) ) ;
Assert . That ( contents , Is . Not . Null ) ;
Assert . That ( contents . Any ( ) , Is . True ) ;
Assert . That ( contents . Count ( ) , Is . GreaterThanOrEqualTo ( 4 ) ) ;
}
}
[Test]
public void ExistContent ( )
{
2020-12-23 11:35:49 +01:00
IScopeProvider provider = ScopeProvider ;
using ( IScope scope = provider . CreateScope ( ) )
2018-06-29 19:52:40 +02:00
{
2020-12-23 11:35:49 +01:00
DocumentRepository repository = CreateRepository ( ( IScopeAccessor ) provider , out _ ) ;
2018-06-29 19:52:40 +02:00
2020-12-23 11:35:49 +01:00
bool exists = repository . Exists ( _subpage . Id ) ;
2018-06-29 19:52:40 +02:00
Assert . That ( exists , Is . True ) ;
}
}
[Test]
public void CountContent ( )
{
2020-12-23 11:35:49 +01:00
IScopeProvider provider = ScopeProvider ;
using ( IScope scope = provider . CreateScope ( ) )
2018-06-29 19:52:40 +02:00
{
2020-12-23 11:35:49 +01:00
DocumentRepository repository = CreateRepository ( ( IScopeAccessor ) provider , out _ ) ;
2018-06-29 19:52:40 +02:00
2020-12-23 11:35:49 +01:00
IQuery < IContent > query = scope . SqlContext . Query < IContent > ( ) . Where ( x = > x . Level = = 2 ) ;
int result = repository . Count ( query ) ;
2018-06-29 19:52:40 +02:00
Assert . That ( result , Is . GreaterThanOrEqualTo ( 2 ) ) ;
}
}
[Test]
public void QueryContentByUniqueId ( )
{
2020-12-23 11:35:49 +01:00
IScopeProvider provider = ScopeProvider ;
using ( IScope scope = provider . CreateScope ( ) )
2018-06-29 19:52:40 +02:00
{
2020-12-23 11:35:49 +01:00
DocumentRepository repository = CreateRepository ( ( IScopeAccessor ) provider , out _ ) ;
2018-06-29 19:52:40 +02:00
2020-12-23 11:35:49 +01:00
IQuery < IContent > query = scope . SqlContext . Query < IContent > ( ) . Where ( x = > x . Key = = new Guid ( "B58B3AD4-62C2-4E27-B1BE-837BD7C533E0" ) ) ;
IContent content = repository . Get ( query ) . SingleOrDefault ( ) ;
2018-06-29 19:52:40 +02:00
Assert . IsNotNull ( content ) ;
2020-10-09 13:08:23 +02:00
Assert . AreEqual ( _textpage . Id , content . Id ) ;
2018-06-29 19:52:40 +02:00
}
}
}
}