Tests/Public/UserManagement/TeamsCallableEntity/Get-TeamsCallableEntity.Tests.ps1

# Module: TeamsFunctions
# Function: Test
# Author: David Eberhardt
# Updated: 23-JUL-2022





InModuleScope TeamsFunctions {
  BeforeAll {
    # Mocking basic connection commands to avoid connectivity related errors
    Mock Assert-AzureADConnection { return $true }
    Mock Assert-MicrosoftTeamsConnection { return $true }
    Mock Test-MicrosoftTeamsConnection { return $true }

    # Splatting Parameters
    $Params = @{
      WarningAction     = 'SilentlyContinue'
      InformationAction = 'SilentlyContinue'
    }

    # Dot Sourcing Mock Objects
    . "$(Get-ParentDirectoryPath -TargetParentDirectory 'Tests' -DirectoryName $PSScriptRoot)\Public\Testing-MockedObjects.ps1"
  }

  Describe -Tags ('Unit', 'Acceptance') "Function 'Get-TeamsCallableEntity'" {
    Context 'Channel - Callable Entity is not found (Team not found)' {
      BeforeEach {
        Mock Get-TeamAndChannel { return $(throw), $(throw) }
        Mock Get-AzureADGroup { return $null }
      }

      It 'should return an Object of type Unknown' {
        $Identity = 'Trunk Company\General'
        (Get-TeamsCallableEntity -Identity $Identity @Params).Identity | Should -BeNullOrEmpty

        $Identity = 'Trunk Company\19:7knN4Rzr3_NUiCsVwEtrHvYWbp_MzqbPp9fEyqujZVc1@thread.tacv2'
        (Get-TeamsCallableEntity -Identity $Identity @Params).Identity | Should -BeNullOrEmpty

        $Identity = '7c105977-d636-419a-b5f3-4885375e432a\General'
        (Get-TeamsCallableEntity -Identity $Identity @Params).Identity | Should -BeNullOrEmpty

        $Identity = '7c105977-d636-419a-b5f3-4885375e432a\19:7knN4Rzr3_NUiCsVwEtrHvYWbp_MzqbPp9fEyqujZVc1@thread.tacv2'
        (Get-TeamsCallableEntity -Identity $Identity @Params).Identity | Should -BeNullOrEmpty
      }
    }

    Context 'Channel - Callable Entity is not found (Team found but Channel not found)' {
      # Reference Object to be created by Get-TeamsCallableEntity - not used in Tests
      BeforeEach {
        Mock Get-TeamAndChannel { return $TeamGood, $(throw) }
        Mock Get-AzureADGroup { return $null }
      }

      It 'should return an Object of type Unknown' {
        $Identity = 'Night Watch\Bribes'
        (Get-TeamsCallableEntity -Identity $Identity @Params).Identity | Should -BeNullOrEmpty

        $Identity = 'Night Watch\19:7knN4Rzr3_NUiCsVwEtrHvYWbp_MzqbPp9fEyqujZVc1@thread.tacv2'
        (Get-TeamsCallableEntity -Identity $Identity @Params).Identity | Should -BeNullOrEmpty

        $Identity = '6c105977-d636-419a-b5f3-4885375e432a\Bribes'
        (Get-TeamsCallableEntity -Identity $Identity @Params).Identity | Should -BeNullOrEmpty

        $Identity = '6c105977-d636-419a-b5f3-4885375e432a\19:7knN4Rzr3_NUiCsVwEtrHvYWbp_MzqbPp9fEyqujZVc1@thread.tacv2'
        (Get-TeamsCallableEntity -Identity $Identity @Params).Identity | Should -BeNullOrEmpty
      }
    }

    Context 'Channel - Callable Entity is found' {
      BeforeEach {
        # Using Testing-MockedObjects.ps1: $TeamGood and $ChannelGood
        Mock Get-TeamAndChannel { return $TeamGood, $ChannelGood }
      }

      It 'should return an Object of type Channel' {
        $Identity = 'Night Watch\Night Watch - Duty Roster'
        (Get-TeamsCallableEntity -Identity $Identity).ObjectType | Should -Be 'Channel'

        $Identity = 'Night Watch\19:6knN4Rzr3_NUiCsVwEtrHvYWbp_MzqbPp9fEyqujZVc1@thread.tacv2'
        (Get-TeamsCallableEntity -Identity $Identity).ObjectType | Should -Be 'Channel'

        $Identity = '6c105977-d636-419a-b5f3-4885375e432a\Night Watch - Duty Roster'
        (Get-TeamsCallableEntity -Identity $Identity).ObjectType | Should -Be 'Channel'

        $Identity = '6c105977-d636-419a-b5f3-4885375e432a\19:6knN4Rzr3_NUiCsVwEtrHvYWbp_MzqbPp9fEyqujZVc1@thread.tacv2'
        (Get-TeamsCallableEntity -Identity $Identity).ObjectType | Should -Be 'Channel'
      }
    }

    Context 'LineURI - String is malformed' {
      It 'should return an Object of type Unknown' {
        # $TFMatchNumber matches 4 to 20 digits - Extensions between 3 and 8 digits - Testing out of bounds
        $Identity = 123
        (Get-TeamsCallableEntity -Identity $Identity @Params).Identity | Should -BeNullOrEmpty

        $Identity = '123;ext=12'
        (Get-TeamsCallableEntity -Identity $Identity @Params).Identity | Should -BeNullOrEmpty

        $Identity = '123456789012345678901'
        (Get-TeamsCallableEntity -Identity $Identity @Params).Identity | Should -BeNullOrEmpty

        $Identity = '12345678901234567890;ext=123456789' # $TFMatchNumber matches extensions 3 to 8 digits
        (Get-TeamsCallableEntity -Identity $Identity @Params).Identity | Should -BeNullOrEmpty
      }
    }

    Context 'LineURI - String is an acceptable string' {
      It 'should return an Object of type ExternalPstn' {
        # $TFMatchNumber matches 4 to 20 digits - Extensions between 3 and 8 digits
        $Identity = '15551234567'
        (Get-TeamsCallableEntity -Identity $Identity).Type | Should -Be 'ExternalPstn'

        $Identity = '+15551234567'
        (Get-TeamsCallableEntity -Identity $Identity).Type | Should -Be 'ExternalPstn'

        $Identity = '+1 (555) 1234567'
        (Get-TeamsCallableEntity -Identity $Identity).Type | Should -Be 'ExternalPstn'

        $Identity = '1 (555) 1234-567'
        (Get-TeamsCallableEntity -Identity $Identity).Type | Should -Be 'ExternalPstn'

        $Identity = '1 (555) 123-4567'
        (Get-TeamsCallableEntity -Identity $Identity).Type | Should -Be 'ExternalPstn'

        $Identity = '1 (555) 123-4-567'
        (Get-TeamsCallableEntity -Identity $Identity).Type | Should -Be 'ExternalPstn'

        $Identity = 'tel:+15551234567'
        (Get-TeamsCallableEntity -Identity $Identity).Type | Should -Be 'ExternalPstn'

        $Identity = '1234'
        (Get-TeamsCallableEntity -Identity $Identity).Type | Should -Be 'ExternalPstn'

        $Identity = 'tel:+12345678901234567890;ext=123'
        (Get-TeamsCallableEntity -Identity $Identity).Type | Should -Be 'ExternalPstn'

        $Identity = 'tel:+12345678901234567890'
        (Get-TeamsCallableEntity -Identity $Identity).Type | Should -Be 'ExternalPstn'

        $Identity = 'tel:+12345678901234567890;ext=12345678'
        (Get-TeamsCallableEntity -Identity $Identity).Type | Should -Be 'ExternalPstn'
      }
    }

    Context 'User - Callable Entity is not found' {
      BeforeEach {
        Mock Get-AzureAdUser { return $null }
        Mock Get-CsOnlineApplicationInstance { return $null }
        Mock Get-AzureADGroup { return $null }
      }
      It 'should return an Object of type Unknown' {
        $Identity = 'TheLastElephant@discworld.onmicrosoft.com'
        (Get-TeamsCallableEntity -Identity $Identity @Params).Identity | Should -BeNullOrEmpty
      }
    }

    Context 'User - Callable Entity is found' {
      BeforeEach {
        # Using Testing-MockedObjects.ps1: $AzureAdUserUserGood1
        Mock Get-AzureAdUser { return $AzureAdUserUserGood1 }
        Mock Get-CsOnlineApplicationInstance { throw }
      }
      It 'should return an Object of type User' {
        $Identity = 'SamVimes@discworld.onmicrosoft.com'
        (Get-TeamsCallableEntity -Identity $Identity @Params).ObjectType | Should -Be 'User'
      }
    }

    Context 'ApplicationInstance - Callable Entity is not found' {
      BeforeEach {
        Mock Get-AzureAdUser { return $null }
        Mock Get-CsOnlineApplicationInstance { return $null }
      }

      It 'should return an Object of type Unknown' {
        $Identity = 'NightWatchDisconnect@discworld.onmicrosoft.com'
        (Get-TeamsCallableEntity -Identity $Identity @Params).Identity | Should -BeNullOrEmpty
      }
    }

    Context 'ApplicationInstance - Callable Entity is found' {
      BeforeEach {
        # Using Testing-MockedObjects.ps1: $AzureAdUserRA, $CsOnlineApplicationInstanceGood1
        Mock Get-AzureAdUser { return $AzureAdUserRAGood1 }
        Mock Get-CsOnlineApplicationInstance { return $CsOnlineApplicationInstanceGood1 }
      }
      Context 'ApplicationInstance is found' {
        It 'should return an Object of type ResourceAccount' {
          $Identity = 'NightWatchRA@discworld.onmicrosoft.com'
          $CallableEntity = Get-TeamsCallableEntity -Identity $Identity @Params
          $CallableEntity.Entity | Should -Be $Identity
          $CallableEntity.ObjectType | Should -Be 'ResourceAccount'
        }
      }
    }

    Context 'Group - Callable Entity is not found' {
      BeforeEach {
        Mock Get-AzureAdUser { return $null }
        Mock Get-CsOnlineApplicationInstance { return $null }
        Mock Get-AzureADGroup { return $null }
      }

      It 'should return an Object of type Unknown' {
        $Identity = 'Committee for Tall People'
        (Get-TeamsCallableEntity -Identity $Identity @Params).Identity | Should -BeNullOrEmpty
      }
    }

    Context 'Group - Callable Entity is found' {
      BeforeEach {
        # Using Testing-MockedObjects.ps1: $AzureAdGroup
        Mock Get-AzureAdUser { return $null }
        Mock Get-CsOnlineApplicationInstance { return $null }
        Mock Get-AzureADGroup { return $AzureAdGroup }
      }

      It 'should return an Object of type Group' {
        $Identity = 'Committee for Equal Heights'
        (Get-TeamsCallableEntity -Identity $Identity @Params).ObjectType | Should -Be 'Group'
      }
    }
  }
}