@@ -202,6 +202,61 @@ private async Task CreateStructureForDepthTests(IRepository repository, string r
202202 }
203203 }
204204
205+ [ TestMethod ]
206+ public async Task IT_Content_Collection_MultiType ( )
207+ {
208+ var cancel = new CancellationTokenSource ( TimeSpan . FromSeconds ( 10 ) ) . Token ;
209+ var repository = await GetRepositoryCollection ( )
210+ . GetRepositoryAsync ( "local" , cancel ) . ConfigureAwait ( false ) ;
211+
212+ // ACT
213+ var request = new LoadCollectionRequest ( )
214+ {
215+ Path = "/Root/IMS/BuiltIn/Portal" ,
216+ Select = new [ ] { "Name" , "Path" , "Type" } ,
217+ OrderBy = new [ ] { "Path" }
218+ } ;
219+ var result = await repository . LoadCollectionAsync ( request , cancel ) . ConfigureAwait ( false ) ;
220+
221+ // ASSERT
222+ var contents = result . ToArray ( ) ;
223+ var types = contents
224+ . Select ( x => x . GetType ( ) )
225+ . Distinct ( )
226+ . Select ( t => t . Name )
227+ . OrderBy ( n => n )
228+ . ToArray ( ) ;
229+ Assert . AreEqual ( "Group User" , string . Join ( " " , types ) ) ;
230+ }
231+
232+ [ TestMethod ]
233+ public async Task IT_Content_Query_MultiType ( )
234+ {
235+ var cancel = new CancellationTokenSource ( TimeSpan . FromSeconds ( 10 ) ) . Token ;
236+ var repository = await GetRepositoryCollection ( )
237+ . GetRepositoryAsync ( "local" , cancel ) . ConfigureAwait ( false ) ;
238+
239+ // ACT
240+ var request = new QueryContentRequest
241+ {
242+ ContentQuery = "InTree:'/Root/IMS'" ,
243+ Select = new [ ] { "Name" , "Path" , "Type" } ,
244+ OrderBy = new [ ] { "Path" }
245+ } ;
246+ var result = await repository . QueryAsync ( request , cancel ) . ConfigureAwait ( false ) ;
247+
248+ // ASSERT
249+ var contents = result . ToArray ( ) ;
250+ var types = contents
251+ . Select ( x => x . GetType ( ) )
252+ . Distinct ( )
253+ . Select ( t => t . Name )
254+ . OrderBy ( n => n )
255+ . ToArray ( ) ;
256+ //Assert.AreEqual("Domains Domain Group Image OrganizationalUnit User", string.Join(" ", types));
257+ Assert . AreEqual ( "Content Domain Group Image OrganizationalUnit User" , string . Join ( " " , types ) ) ;
258+ }
259+
205260 /* ================================================================================================== ACTIONS */
206261
207262 public class File : Content
@@ -421,7 +476,7 @@ public TestMemo(IRestCaller restCaller, ILogger<TestMemo> logger) : base(restCal
421476 [ TestMethod ]
422477 public async Task IT_Content_T_Update ( )
423478 {
424- var cancel = new CancellationTokenSource ( TimeSpan . FromSeconds ( 10 ) ) . Token ;
479+ var cancel = new CancellationTokenSource ( ) . Token ;
425480 var repository =
426481 await GetRepositoryCollection (
427482 services => { services . RegisterGlobalContentType < TestMemo > ( "Memo" ) ; } )
@@ -485,7 +540,7 @@ await GetRepositoryCollection(
485540 [ TestMethod ]
486541 public async Task IT_Content_T_Update_ReferenceList ( )
487542 {
488- var cancel = new CancellationTokenSource ( TimeSpan . FromSeconds ( 10 ) ) . Token ;
543+ var cancel = new CancellationTokenSource ( TimeSpan . FromSeconds ( 120 ) ) . Token ;
489544 var repository =
490545 await GetRepositoryCollection (
491546 services => { services . RegisterGlobalContentType < TestMemo > ( "Memo" ) ; } )
@@ -508,22 +563,22 @@ await GetRepositoryCollection(
508563
509564 // 2 - Create container and some memos
510565 var container = repository . CreateContent ( rootPath , containerType , containerName ) ;
511- await container . SaveAsync ( ) . ConfigureAwait ( false ) ;
566+ await container . SaveAsync ( cancel ) . ConfigureAwait ( false ) ;
512567 var referredMemos = new Content [ 3 ] ;
513568 for ( int i = 0 ; i < referredMemos . Length ; i ++ )
514569 {
515570 referredMemos [ i ] = repository . CreateContent ( container . Path , contentTypeName , $ "ReferredMemo{ i + 1 } ") ;
516571 //referredMemos[i]["MemoType"] = Array.Empty<string>();
517572 //referredMemos[i]["MemoType"] = new[] { "generic" };
518573 ( ( TestMemo ) referredMemos [ i ] ) . MemoType = Array . Empty < string > ( ) ;
519- await referredMemos [ i ] . SaveAsync ( ) . ConfigureAwait ( false ) ;
574+ await referredMemos [ i ] . SaveAsync ( cancel ) . ConfigureAwait ( false ) ;
520575 }
521576
522577 // 3 - Create brand new content and test its existence
523578 var content = repository . CreateContent < TestMemo > ( containerPath , null , contentName ) ;
524579 content . MemoType = Array . Empty < string > ( ) ;
525580 content . SeeAlso = referredMemos . Take ( 2 ) . ToList ( ) ;
526- await content . SaveAsync ( ) . ConfigureAwait ( false ) ;
581+ await content . SaveAsync ( cancel ) . ConfigureAwait ( false ) ;
527582 var contentId = content . Id ;
528583 Assert . IsTrue ( contentId > 0 ) ;
529584
@@ -546,7 +601,7 @@ await GetRepositoryCollection(
546601
547602 // 6 - Update content
548603 loadedContent . SeeAlso [ 1 ] = referredMemos [ 2 ] ;
549- await loadedContent . SaveAsync ( ) . ConfigureAwait ( false ) ;
604+ await loadedContent . SaveAsync ( cancel ) . ConfigureAwait ( false ) ;
550605
551606 // 7 - Load updated content
552607 var reloadedContent = await repository . LoadContentAsync < TestMemo > ( expandedRequest , cancel ) . ConfigureAwait ( false ) ;
@@ -574,7 +629,7 @@ await GetRepositoryCollection(
574629 wrongContent . SeeAlso . Add ( referredMemos [ 2 ] ) ;
575630 try
576631 {
577- await wrongContent . SaveAsync ( ) . ConfigureAwait ( false ) ;
632+ await wrongContent . SaveAsync ( cancel ) . ConfigureAwait ( false ) ;
578633 Assert . Fail ( "The expected ApplicationException was not thrown." ) ;
579634 }
580635 catch ( ApplicationException e )
@@ -590,6 +645,76 @@ await GetRepositoryCollection(
590645 Assert . IsFalse ( await repository . IsContentExistsAsync ( path , cancel ) . ConfigureAwait ( false ) ) ;
591646 }
592647
648+ /* ============================================================================================= ALLOWED CHILD TYPES */
649+
650+ [ TestMethod ]
651+ public async Task IT_Content_AllowedChildTypes ( )
652+ {
653+ var cancel = new CancellationTokenSource ( ) . Token ;
654+ var repository = await GetRepositoryCollection ( )
655+ . GetRepositoryAsync ( "local" , cancel ) . ConfigureAwait ( false ) ;
656+
657+ await repository . DeleteContentAsync ( new [ ] { "/Root/Content/DocLib-1" } , true , cancel ) . ConfigureAwait ( false ) ;
658+
659+ // ACT-1: /Root/Content
660+ var request = new LoadContentRequest
661+ {
662+ Path = "/Root/Content" ,
663+ Expand = new [ ] { "AllowedChildTypes" , "EffectiveAllowedChildTypes" } ,
664+ Select = new [ ] { "*" , "AllowedChildTypes/Name" , "EffectiveAllowedChildTypes/Name" }
665+ } ;
666+ var content1 = await repository . LoadContentAsync < Workspace > ( request , cancel ) . ConfigureAwait ( false ) ;
667+
668+ // ASSERT-1: AllowedChildTypes fields are not null, not empty
669+ Assert . IsNotNull ( content1 . AllowedChildTypes ) ;
670+ Assert . IsNotNull ( content1 . EffectiveAllowedChildTypes ) ;
671+ Assert . IsTrue ( content1 . AllowedChildTypes . Any ( ) ) ;
672+ Assert . IsTrue ( content1 . EffectiveAllowedChildTypes . Any ( ) ) ;
673+
674+ // ACT-2: Create a doclib
675+ var docLib1 = repository . CreateContent ( "/Root/Content" , "DocumentLibrary" , "DocLib-1" ) ;
676+ //docLib1.AllowedChildTypes = new ContentType[] { taskListContentType, memoListContentType};
677+ await docLib1 . SaveAsync ( cancel ) . ConfigureAwait ( false ) ;
678+
679+ // ASSERT-2
680+ request = new LoadContentRequest
681+ {
682+ Path = "/Root/Content/DocLib-1" ,
683+ Expand = new [ ] { "AllowedChildTypes" , "EffectiveAllowedChildTypes" } ,
684+ Select = new [ ] { "*" , "AllowedChildTypes/Name" , "EffectiveAllowedChildTypes/Name" }
685+ } ;
686+ docLib1 = await repository . LoadContentAsync < Content > ( request , cancel ) . ConfigureAwait ( false ) ;
687+ var allowedChildTypes = docLib1 . AllowedChildTypes . Select ( x => x . Name ) . OrderBy ( x => x ) . ToArray ( ) ;
688+ var effectiveChildTypes = docLib1 . EffectiveAllowedChildTypes . Select ( x => x . Name ) . OrderBy ( x => x ) . ToArray ( ) ;
689+ Assert . AreEqual ( "" , string . Join ( " " , allowedChildTypes ) ) ;
690+ Assert . AreEqual ( "File Folder SystemFolder" , string . Join ( " " , effectiveChildTypes ) ) ;
691+
692+ // ACT-3: Update a doclib with childType control
693+ var taskListContentType = await repository . LoadContentAsync < ContentType > (
694+ "/Root/System/Schema/ContentTypes/GenericContent/Folder/ContentList/ItemList/TaskList" , cancel )
695+ . ConfigureAwait ( false ) ;
696+ var memoListContentType = await repository . LoadContentAsync < ContentType > (
697+ "/Root/System/Schema/ContentTypes/GenericContent/Folder/ContentList/ItemList/MemoList" , cancel )
698+ . ConfigureAwait ( false ) ;
699+ docLib1 . AllowedChildTypes = new ContentType [ ] { taskListContentType , memoListContentType } ;
700+ await docLib1 . SaveAsync ( cancel ) . ConfigureAwait ( false ) ;
701+
702+ // ASSERT-3
703+ request = new LoadContentRequest
704+ {
705+ Path = "/Root/Content/DocLib-1" ,
706+ Expand = new [ ] { "AllowedChildTypes" , "EffectiveAllowedChildTypes" } ,
707+ Select = new [ ] { "*" , "AllowedChildTypes/Name" , "EffectiveAllowedChildTypes/Name" }
708+ } ;
709+ docLib1 = await repository . LoadContentAsync < Content > ( request , cancel ) . ConfigureAwait ( false ) ;
710+ allowedChildTypes = docLib1 . AllowedChildTypes ? . Select ( x => x . Name ) . OrderBy ( x => x )
711+ . ToArray ( ) ?? Array . Empty < string > ( ) ;
712+ effectiveChildTypes = docLib1 . EffectiveAllowedChildTypes ? . Select ( x => x . Name ) . OrderBy ( x => x )
713+ . ToArray ( ) ?? Array . Empty < string > ( ) ;
714+ Assert . AreEqual ( "MemoList TaskList" , string . Join ( " " , allowedChildTypes ) ) ;
715+ Assert . AreEqual ( "MemoList SystemFolder TaskList" , string . Join ( " " , effectiveChildTypes ) ) ;
716+ }
717+
593718 /* ================================================================================================== OPERATIONS */
594719
595720 [ TestMethod ]
0 commit comments