Tests/Items.Tests.ps1

#Requires -version 3.0
Set-StrictMode -Version Latest

$here = Split-Path -Parent $MyInvocation.MyCommand.Path

<#
**************************************************
* Tests
**************************************************
#>


Describe "Core Service Item Tests" {
    BeforeAll {
        $parent = Split-Path -Parent $here
        
        Get-Module Tridion-CoreService | Remove-Module
        $modulesToImport = @('Tridion-CoreService.psd1', 'Items.psm1');
        $modulesToImport | ForEach-Object { Import-Module (Join-Path $parent $_) -Force; }
    }

    # InModuleScope allows us to mock the private, non-exported functions in the module
    InModuleScope Items {
    
        # ***********************
        # Mock Items
        # ***********************
        $folder1 = [PSCustomObject]@{ Id = 'tcm:1-2-2'; Title = 'Building Blocks'};
        $page1 = [PSCustomObject]@{ Id = 'tcm:1-10-64'; Title = 'Page 1'};
        $publication1 = [PSCustomObject]@{ Id = 'tcm:0-1-1'; Title = 'Publication 1'; Parents = @()};
        $publication2 = [PSCustomObject]@{ Id = 'tcm:0-2-1'; Title = 'Publication 2'; Parents = @($publication1.Id)};
        $publication3 = [PSCustomObject]@{ Id = 'tcm:0-3-1'; Title = 'Web Publication 1'; Parents = @($publication2.Id)};
        $publication4 = [PSCustomObject]@{ Id = 'tcm:0-4-1'; Title = 'Web Publication 2'; Parents = @($publication2.Id)};
        $sg1 = [PSCustomObject]@{ Id = 'tcm:1-33-4'; Title = 'Root Structure Group'};
        $target1 = [PSCustomObject]@{ Id = 'tcm:0-1-65537'; Title = 'Publication Target 1'};
        $target2 = [PSCustomObject]@{ Id = 'tcm:0-2-65537'; Title = 'Publication Target 2'};

        $existingItems = @{
            $folder1.Id = $folder1;
            $page1.Id = $page1;
            $publication1.Id = $publication1;
            $publication2.Id = $publication2;
            $publication3.Id = $publication3;
            $publication4.Id = $publication4;
            $sg1.Id = $sg1;
            $target1.Id = $target1;
            $target2.Id = $target2;
        };
        
        $allPublications = @($publication1, $publication2, $publication3, $publication4);
        
        
        # ***********************
        # Mocks
        # ***********************
        Mock _GetDefaultData { 
            $result = [PSCustomObject]@{ Id = 'tcm:0-0-0'; Title = $Name; _ItemType = $ItemType};
            
            switch($ItemType) 
            {
                1 { Add-Member -InputObject $result -MemberType NoteProperty -Name 'Parents' -Value @();}
            }
            return $result; 
        }
        Mock _GetSystemWideList {
            if ($filter -is [Tridion.ContentManager.CoreService.Client.PublicationTargetsFilterData])
            {
                return @($target1, $target2);
            }
        
            if ($filter -is [Tridion.ContentManager.CoreService.Client.PublicationsFilterData])
            {
                $pubType = $filter.PublicationTypeName;
                switch ($pubType)
                {
                    'Web' { return @($publication3, $publication4); }
                    'Content' { return @($publication1, $publication2, $publication3); }
                    default { return $allPublications; }
                }
                return @($publication1, $publication2);
            }
        }
        Mock _GetItem {
            if ($Id -in $existingItems.Keys)
            {
                return $existingItems[$Id];
            }
            
            throw "Item does not exist";
        }
        Mock _SaveItem { 
            $publicationId = 1;
            $itemType = $Item._ItemType;
            
            switch($itemType)
            {
                1 { $publicationId = 0; }
                2 {}
                64 {}
                default { throw "Unexpected item type: $itemType"; }
            }
            
            $random = Get-Random -Minimum 10 -Maximum 500;
            $Item.Id ="tcm:$publicationId-$random-$itemType";
            return $Item;
        }
        Mock _IsExistingItem { return ($Id -in $existingItems.Keys); }            
        Mock _DeleteItem { if (!$Id -in $existingItems.Keys) { throw "Item does not exist." } }
        Mock Close-TridionCoreServiceClient {}
        Mock Get-TridionCoreServiceClient { return [PSCustomObject]@{}; }
        
        
        # ***********************
        # Tests
        # ***********************
        Context "Get-TridionItem" {
            It "validates input parameters" {
                { Get-TridionItem -Id $null } | Should Throw;
                { Get-TridionItem -Id '' } | Should Throw;
            }
            
            It "disposes the client after use" {
                Get-TridionItem -Id $page1.Id | Out-Null;
                Assert-MockCalled Close-TridionCoreServiceClient -Times 1 -Scope It;
            }
            
            It "supports look-up by ID" {
                $item = Get-TridionItem -Id $page1.Id;
                Assert-MockCalled _GetItem -Times 1 -Scope It;
                $item | Should Be $page1;
            }
            
            It "handles items that do not exist" {
                Get-TridionItem -Id 'tcm:0-99-64' | Should Be $null;
                Get-TridionItem -Id 'tcm:0-0-0' | Should Be $null;
            }
            
            It "supports piping in the ID" {
                $item = ($page1.Id | Get-TridionItem);
                Assert-MockCalled _GetItem -Times 1 -Scope It -ParameterFilter { $Id -eq $page1.Id };
                $item | Should Be $page1;
            }
            
            It "supports piping in the ID as object" {
                $item = ($page1 | Get-TridionItem);
                Assert-MockCalled _GetItem -Times 1 -Scope It -ParameterFilter { $Id -eq $page1.Id };
                $item | Should Be $page1;
            }
            
            It "supports piping in the ID by property name" {
                $testInput = [PSCustomObject]@{ Id = $page1.Id };
                $item = ($testInput | Get-TridionItem);
                Assert-MockCalled _GetItem -Times 1 -Scope It -ParameterFilter { $Id -eq $page1.Id };
                $item | Should Be $page1;
            }
        }

        Context "Get-TridionPublication" {
            It "validates input parameters" {
                { Get-TridionPublication -Id $null } | Should Throw;
                { Get-TridionPublication -Id '' } | Should Throw;
                { Get-TridionPublication -Id 'tcm:2-8-8' } | Should Throw "Unexpected item type '8'. Expected '1'.";
                { Get-TridionPublication -Id 'tcm:2-1' } | Should Throw "Unexpected item type '16'. Expected '1'.";
            }
            
            It "disposes the client after use" {
                Get-TridionPublication | Out-Null;
                Assert-MockCalled Close-TridionCoreServiceClient -Times 1 -Scope It;
            }
            
            It "supports look-up by ID" {
                $publication = Get-TridionPublication -Id $publication1.Id;
                Assert-MockCalled _GetItem -Times 1 -Scope It;
                $publication | Should Be $publication1;
            }
            
            It "supports look-up by name" {
                $publication = Get-TridionPublication -Name $publication1.Title;
                Assert-MockCalled _GetSystemWideList -Times 1 -Scope It;
                $publication | Should Be $publication1;
            }
            
            It "supports look-up by partial name" {
                $publications = Get-TridionPublication -Name 'Publication *';
                Assert-MockCalled _GetSystemWideList -Times 1 -Scope It;
                $publications[0] | Should Be $publication1;
                $publications[1] | Should Be $publication2;
            }
            
            It "supports look-up by Publication Type" {
                $publications = Get-TridionPublication -PublicationType 'Web';
                Assert-MockCalled _GetSystemWideList -Times 1 -Scope It;
                $publications | Should Be @($publication3, $publication4);
            }
            
            It "supports expanding properties in list by name" {
                # A list will typically only load partial data
                $publication = Get-TridionPublication -Name $publication2.Title -ExpandProperties;
                Assert-MockCalled _GetSystemWideList -Times 1 -Scope It;
                Assert-MockCalled _GetItem -Times 1 -Scope It;
                $publication | Should Be $publication2;
            }

            It "supports expanding properties in list by Publication Type" {
                # A list will typically only load partial data
                $publications = Get-TridionPublication -PublicationType 'Web' -ExpandProperties;
                Assert-MockCalled _GetSystemWideList -Times 1 -Scope It;
                Assert-MockCalled _GetItem -Times 2 -Scope It;
                $publications.Count | Should Be 2;
                $publications[0] | Should Be $publication3;
                $publications[1] | Should Be $publication4;
            }

            It "supports piping in the ID by property name" {
                $testInput = [PSCustomObject]@{ Id = $publication1.Id };
                $item = ($testInput | Get-TridionPublication);
                Assert-MockCalled _GetItem -Times 1 -Scope It -ParameterFilter { $Id -eq $publication1.Id };
                $item | Should Be $publication1;
            }            
            
            It "supports piping in the title by property name" {
                $testInput = [PSCustomObject]@{ Title = $publication2.Title };
                $item = ($testInput | Get-TridionPublication);
                Assert-MockCalled _GetSystemWideList -Times 1 -Scope It;
                $item | Should Be $publication2;
            }
            
            It "supports piping in the publication type by property name" {
                $testInput = @([PSCustomObject]@{ PublicationType = 'Web'}, [PSCustomObject]@{ PublicationType = 'Content' });
                $items = ($testInput | Get-TridionPublication);
                Assert-MockCalled _GetSystemWideList -Times 2 -Scope It -ParameterFilter { $Filter.PublicationTypeName -in @('Web', 'Content') };
                
                $items.Count | Should Be 5;
                $items[0] | Should Be $publication3;
                $items[1] | Should Be $publication4;
                $items[2] | Should Be $publication1;
                $items[3] | Should Be $publication2;
                $items[4] | Should Be $publication3;
            }
            
            It "returns a list of all Publications when called without parameters" {
                $publications = Get-TridionPublication;
                Assert-MockCalled _GetSystemWideList -Times 1 -Scope It;
                $publications | Should Be $allPublications;
            }
            
            It "handles items that do not exist" {
                Get-TridionPublication -Id 'tcm:0-99-1' | Should Be $null;
                Get-TridionPublication -Id 'tcm:0-0-0' | Should Be $null;
            }
            
            It "has aliases for backwards-compatibility (Get-TridionPublications => Get-TridionPublication)" {
                $alias = Get-Alias -Name Get-TridionPublications;
                $alias.Definition | Should Be 'Get-TridionPublication';
                
                # Check that it also works as expected (i.e. gets a list of items)
                $publications = Get-TridionPublications;
                Assert-MockCalled _GetSystemWideList -Times 1 -Scope It;
                $publications | Should Be $allPublications;
            }
            
            It "has aliases for backwards-compatibility (-Title => -Name)" {
                $publication = Get-TridionPublication -Title $publication1.Title;
                Assert-MockCalled _GetSystemWideList -Times 1 -Scope It;
                $publication | Should Be $publication1;
            }
        }

        Context "Get-TridionPublicationTarget" {
            It "validates input parameters" {
                { Get-TridionPublicationTarget -Id $null } | Should Throw;
                { Get-TridionPublicationTarget -Id '' } | Should Throw;
                { Get-TridionPublicationTarget -Id 'tcm:2-8-8' } | Should Throw "Unexpected item type '8'. Expected '65537'.";
                { Get-TridionPublicationTarget -Id 'tcm:2-65537' } | Should Throw "Unexpected item type '16'. Expected '65537'.";
            }
            
            It "disposes the client after use" {
                Get-TridionPublicationTarget | Out-Null;
                Assert-MockCalled Close-TridionCoreServiceClient -Times 1 -Scope It;
            }
            
            It "supports look-up by ID" {
                $target = Get-TridionPublicationTarget -Id $target1.Id;
                Assert-MockCalled _GetItem -Times 1 -Scope It;
                $target | Should Be $target1;
            }
            
            It "supports look-up by title" {
                $target = Get-TridionPublicationTarget -Name $target1.Title;
                Assert-MockCalled _GetSystemWideList -Times 1 -Scope It;
                $target | Should Be $target1;
            }
            
            It "supports getting a list when called without parameters" {
                $targets = Get-TridionPublicationTarget;
                Assert-MockCalled _GetSystemWideList -Times 1 -Scope It;
                $targets | Should Be @($target1, $target2);
            }
            
            It "supports expanding properties in list" {
                # A list will typically only load partial data
                $target = Get-TridionPublicationTarget -Name $target2.Title -ExpandProperties;
                Assert-MockCalled _GetSystemWideList -Times 1 -Scope It;
                Assert-MockCalled _GetItem -Times 1 -Scope It;
                $target | Should Be $target2;
            }
            
            It "supports piping in the ID by property name" {
                $testInput = [PSCustomObject]@{ Id = $target1.Id };
                $item = ($testInput | Get-TridionPublicationTarget);
                Assert-MockCalled _GetItem -Times 1 -Scope It -ParameterFilter { $Id -eq $target1.Id };
                $item | Should Be $target1;
            }            
            
            It "supports piping in the title by property name" {
                $testInput = [PSCustomObject]@{ Title = $target1.Title };
                $item = ($testInput | Get-TridionPublicationTarget);
                Assert-MockCalled _GetSystemWideList -Times 1 -Scope It;
                $item | Should Be $target1;
            }            
            
            It "supports piping in the title values" {
                $testInput = @($target1.Title, $target2.Title);
                $items = ($testInput | Get-TridionPublicationTarget);
                Assert-MockCalled _GetSystemWideList -Times 2 -Scope It;
                $items.Count | Should Be 2;
                $items[0] | Should Be $target1;
                $items[1] | Should Be $target2;
            }            
            
            It "handles items that do not exist" {
                Get-TridionPublicationTarget -Id 'tcm:0-99-65537' | Should Be $null;                
                Get-TridionPublicationTarget -Id 'tcm:0-0-0' | Should Be $null;
            }
            
            It "has aliases for backwards-compatibility (Get-TridionPublicationTargets => Get-TridionPublicationTarget)" {
                $alias = Get-Alias -Name Get-TridionPublicationTargets;
                $alias.Definition | Should Be 'Get-TridionPublicationTarget';
                
                # Check that it also works as expected (i.e. gets a list of items)
                $targets = Get-TridionPublicationTargets;
                Assert-MockCalled _GetSystemWideList -Times 1 -Scope It;
                $targets | Should Be @($target1, $target2);
            }
            
            It "has aliases for backwards-compatibility (-Title => -Name)" {
                $target = Get-TridionPublicationTarget -Title $target1.Title;
                Assert-MockCalled _GetSystemWideList -Times 1 -Scope It;
                $target | Should Be $target1;
            }
        }

        Context "New-TridionItem" {
            It "validates input parameters" {
                { New-TridionItem -ItemType $null -Name 'Test'} | Should Throw 'Invalid item type: 0';
                { New-TridionItem -ItemType -1 -Name 'Test'} | Should Throw 'Invalid item type: -1';
                { New-TridionItem -ItemType 0 -Name 'Test'} | Should Throw 'Invalid item type: 0';
                { New-TridionItem -ItemType 3 -Name 'Test'} | Should Throw 'Invalid item type: 3';
                { New-TridionItem -ItemType 1 -Name $null} | Should Throw;
            }
            
            It "disposes the client after use" {
                New-TridionItem -ItemType 64 -Name 'Testing Dispose' | Out-Null;
                Assert-MockCalled Close-TridionCoreServiceClient -Times 1 -Scope It;
            }
            
            It "creates a new Page" {
                $itemTitle = 'My New Page';
                $item = New-TridionItem -ItemType 64 -Name $itemTitle -Parent $sg1.Id;
                Assert-MockCalled _GetDefaultData -Times 1 -Scope It -ParameterFilter { ($ItemType -eq 64) -and ($Name -eq $itemTitle) -and ($Parent -eq $sg1.Id) };
                Assert-MockCalled _SaveItem -Times 1 -Scope It;
                $item.Title | Should Be $itemTitle;
                $item.Id.StartsWith('tcm:1-') | Should Be $true;
                _GetItemType $item.Id | Should Be 64;
            }

            It "supports piping in the parent" {
                $itemTitle = 'Testing pipeline parent';
                $item = (Get-TridionItem -Id $folder1.Id | New-TridionItem -ItemType 2 -Name $itemTitle);
                Assert-MockCalled _GetDefaultData -Times 1 -Scope It -ParameterFilter { $ItemType -eq 2 -and $Name -eq $itemTitle -and $Parent -eq $folder1.Id };
                Assert-MockCalled _SaveItem -Times 1 -Scope It;
                $item.Title | Should Be $itemTitle;
            }
            
            It "has aliases for backwards-compatibility (-Title => -Name)" {
                $itemTitle = 'Testing Title alias for Name';
                $item = New-TridionItem -ItemType 64 -Title $itemTitle -Parent $sg1.Id;
                Assert-MockCalled _GetDefaultData -Times 1 -Scope It -ParameterFilter { ($ItemType -eq 64) -and ($Name -eq $itemTitle) -and ($Parent -eq $sg1.Id) };
                Assert-MockCalled _SaveItem -Times 1 -Scope It;
                $item.Title | Should Be $itemTitle;
                $item.Id.StartsWith('tcm:1-') | Should Be $true;
                _GetItemType $item.Id | Should Be 64;
            }
        }

        Context "New-TridionPublication" {
            It "validates input parameters" {
                { New-TridionPublication -Name $null} | Should Throw;
                { New-TridionPublication -Name ''} | Should Throw;
            }

            It "disposes the client after use" {
                New-TridionPublication -Name 'Testing Dispose' | Out-Null;
                Assert-MockCalled Close-TridionCoreServiceClient -Times 1 -Scope It;
            }
            
            It "creates a new Publication with the given title" {
                $itemTitle = 'Testing creation';
                $publication = New-TridionPublication -Name $itemTitle;
                Assert-MockCalled _GetDefaultData -Times 1 -Scope It -ParameterFilter { ($ItemType -eq 1) -and ($Name -eq $itemTitle) -and ($Parent -eq $null) };
                Assert-MockCalled _SaveItem -Times 1 -Scope It -ParameterFilter { ($Item.Title -eq $itemTitle) };
                $publication.Title | Should Be $itemTitle;
                $publication.Id.StartsWith('tcm:0-') | Should Be $true;
                _GetItemType $publication.Id | Should Be 1;
            }
            
            It "creates a new Publication with a single parent" {
                $itemTitle = 'Testing creation with single parent';
                $publication = New-TridionPublication -Name $itemTitle -Parent $publication1;
                Assert-MockCalled _GetDefaultData -Times 1 -Scope It -ParameterFilter { ($ItemType -eq 1) -and ($Name -eq $itemTitle) -and ($Parent -eq $null) };
                Assert-MockCalled _SaveItem -Times 1 -Scope It -ParameterFilter { ($Item.Title -eq $itemTitle) -and ($Item.Parents.Count -eq 1) };
                $publication.Title | Should Be $itemTitle;
                $publication.Id.StartsWith('tcm:0-') | Should Be $true;
                _GetItemType $publication.Id | Should Be 1;
                $publication.Parents[0].IdRef | Should Be $publication1.Id;
            }
            
            It "creates a new Publication with a multiple parents" {
                $itemTitle = 'Testing creation with multiple parents';
                $publication = New-TridionPublication -Name $itemTitle -Parent @($publication1, $publication2);
                Assert-MockCalled _GetDefaultData -Times 1 -Scope It -ParameterFilter { ($ItemType -eq 1) -and ($Name -eq $itemTitle) -and ($Parent -eq $null) };
                Assert-MockCalled _SaveItem -Times 1 -Scope It -ParameterFilter { ($Item.Title -eq $itemTitle) -and ($Item.Parents.Count -eq 2) };
                $publication.Title | Should Be $itemTitle;
                $publication.Id.StartsWith('tcm:0-') | Should Be $true;
                _GetItemType $publication.Id | Should Be 1;
                $publication.Parents[0].IdRef | Should Be $publication1.Id;
                $publication.Parents[1].IdRef | Should Be $publication2.Id;
            }

            It "supports piping in the parent" {
                $itemTitle = 'Testing pipeline parent';
                $publication = (Get-TridionPublication -Id $publication4.Id | New-TridionPublication -Name $itemTitle);
                Assert-MockCalled _GetDefaultData -Times 1 -Scope It -ParameterFilter { $ItemType -eq 1 -and $Name -eq $itemTitle -and $Parent -eq $null };
                Assert-MockCalled _SaveItem -Times 1 -Scope It -ParameterFilter { ($Item.Title -eq $itemTitle) -and ($Item.Parents.Count -eq 1) };
                $publication.Title | Should Be $itemTitle;
                $publication.Parents[0].IdRef | Should Be $publication4.Id;
            }

            It "supports piping in multiple parents" {
                $itemTitle = 'Testing pipeline parent';
                $publication = Get-TridionPublication -PublicationType 'Web' | New-TridionPublication -Name $itemTitle;
                Assert-MockCalled _GetDefaultData -Times 1 -Scope It -ParameterFilter { $ItemType -eq 1 -and $Name -eq $itemTitle -and $Parent -eq $null };
                Assert-MockCalled _SaveItem -Times 1 -Scope It -ParameterFilter { ($Item.Title -eq $itemTitle) -and ($Item.Parents.Count -eq 2) };
                $publication.Title | Should Be $itemTitle;
                $publication.Parents[0].IdRef | Should Be $publication3.Id;
                $publication.Parents[1].IdRef | Should Be $publication4.Id;
            }

            It "has aliases for backwards-compatibility (Parents => Parent)" {
                $itemTitle = 'Testing creation with multiple parents';
                $publication = New-TridionPublication -Title $itemTitle -Parents @($publication1, $publication2);
                Assert-MockCalled _GetDefaultData -Times 1 -Scope It -ParameterFilter { ($ItemType -eq 1) -and ($Name -eq $itemTitle) -and ($Parent -eq $null) };
                Assert-MockCalled _SaveItem -Times 1 -Scope It -ParameterFilter { ($Item.Title -eq $itemTitle) -and ($Item.Parents.Count -eq 2) };
                $publication.Title | Should Be $itemTitle;
                $publication.Id.StartsWith('tcm:0-') | Should Be $true;
                _GetItemType $publication.Id | Should Be 1;
                $publication.Parents[0].IdRef | Should Be $publication1.Id;
                $publication.Parents[1].IdRef | Should Be $publication2.Id;
            }
            
            It "has aliases for backwards-compatibility (-Title => -Name)" {
                $itemTitle = 'Testing Title alias for Name';
                $publication = New-TridionPublication -Title $itemTitle;
                Assert-MockCalled Close-TridionCoreServiceClient -Times 1 -Scope It;
                $publication.Title | Should Be $itemTitle;
            }
        }

        Context "Remove-TridionItem" {
            It "validates input parameters" {
                { Remove-TridionItem -Id $null} | Should Throw;
                { Remove-TridionItem -Id ''} | Should Throw;
            }
            
            It "supports positional parameter" {
                Remove-TridionItem $publication4.Id;
                Assert-MockCalled _DeleteItem -Times 1 -Scope It -ParameterFilter { $Id -eq $publication4.Id};
            }
            
            It "supports piping in the ID" {
                $publication4.Id | Remove-TridionItem;
                Assert-MockCalled _DeleteItem -Times 1 -Scope It -ParameterFilter { $Id -eq $publication4.Id};
            }
            
            It "supports piping in the ID as object" {
                $publication4 | Remove-TridionItem;
                Assert-MockCalled _DeleteItem -Times 1 -Scope It -ParameterFilter { $Id -eq $publication4.Id};
            }
            
            It "handles items that do not exist" {
                $itemId = 'tcm:0-99-32';
                Remove-TridionItem -Id $itemId;
                Assert-MockCalled _DeleteItem -Times 0 -Scope It;
                Assert-MockCalled _IsExistingItem -Times 1 -Scope It -ParameterFilter { $Id -eq $itemId};

                $itemId = 'tcm:0-0-0';
                Remove-TridionItem -Id $itemId;
                Assert-MockCalled _DeleteItem -Times 0 -Scope It;
                Assert-MockCalled _IsExistingItem -Times 1 -Scope It -ParameterFilter { $Id -eq $itemId};
            }
            
            It "has aliases for backwards-compatibility (Item => Id)" {
                Remove-TridionItem -Item $publication4;
                Assert-MockCalled _DeleteItem -Times 1 -Scope It -ParameterFilter { $Id -eq $publication4.Id};
            }
        }

        Context "Test-TridionItem" {
            It "validates input parameters" {
                { Test-TridionItem -Id $null} | Should Throw;
                { Test-TridionItem -Id ''} | Should Throw;
            }
            
            It "disposes the client after use" {
                Test-TridionItem $page1.Id | Out-Null;
                Assert-MockCalled Close-TridionCoreServiceClient -Times 1 -Scope It;
            }
            
            It "supports positional parameter" {
                $exists = (Test-TridionItem $publication4.Id);
                Assert-MockCalled _IsExistingItem -Times 1 -Scope It -ParameterFilter { $Id -eq $publication4.Id};
                $exists | Should Be $true;
            }
            
            It "supports piping in the ID" {
                $exists = ($publication4.Id | Test-TridionItem);
                Assert-MockCalled _IsExistingItem -Times 1 -Scope It #-ParameterFilter { $Id -eq $publication4.Id};
                $exists | Should Be $true;
            }
            
            It "supports piping in the ID as object" {
                $exists = ($publication4 | Test-TridionItem);
                Assert-MockCalled _IsExistingItem -Times 1 -Scope It #-ParameterFilter { $Id -eq $publication4.Id};
                $exists | Should Be $true;
            }
            
            It "handles items that do not exist" {
                $itemId = 'tcm:0-99-32';
                $exists = Test-TridionItem -Id $itemId;
                Assert-MockCalled _IsExistingItem -Times 1 -Scope It #-ParameterFilter { $Id -eq $itemId};
                $exists | Should Be $false;

                $itemId = 'tcm:0-0-0';
                Test-TridionItem -Id $itemId;
                Assert-MockCalled _IsExistingItem -Times 1 -Scope It #-ParameterFilter { $Id -eq $itemId};
                $exists | Should Be $false;
            }
        }
    }
}