FindObject.E2E.Tests.ps1

#Requires -Modules Pester

<#
.SYNOPSIS
    Comprehensive Opaque-Box End-to-End (E2E) Test Suite for FindObject.

.DESCRIPTION
    Validates FindObject v2.0 across 4 Tiers:
      - Tier 1: Feature Coverage (Equivalence classes covering F1 through F12)
      - Tier 2: Boundary & Corner Cases (Extreme limits, empty/whitespace, edge inputs)
      - Tier 3: Cross-Feature Combinations (Pairwise & multi-feature interactions)
      - Tier 4: Real-World Application Scenarios (Realistic sysadmin/DevSecOps workloads)

    Derived strictly from ORIGINAL_REQUEST.md and PROJECT.md.
    Maintained independently by E2E Test Writer.
#>


BeforeAll {
    # Isolate module path to local AppData to prevent OneDrive dehydration locks
    $env:PSModulePath = "C:\Users\Tony\AppData\Local\PowerShell\Modules;" + $env:PSModulePath
    Import-Module "C:\Users\Tony\AppData\Local\PowerShell\Modules\Pester\5.6.1\Pester.psd1" -Force

    $script:ModuleDir = $PSScriptRoot
    $script:CoreManifest = Join-Path $script:ModuleDir "FindObject.psd1"
    $script:CorePsm1 = Join-Path $script:ModuleDir "FindObject.psm1"
    $script:IntuneManifest = Join-Path $script:ModuleDir "FindObject.Intune.psd1"
    $script:IntunePsm1 = Join-Path $script:ModuleDir "FindObject.Intune.psm1"

    # Reset any active module in session
    Get-Module FindObject, FindObject.Intune | Remove-Module -Force -ErrorAction SilentlyContinue

    if (Test-Path $script:CoreManifest) {
        Import-Module $script:CoreManifest -Force
    } else {
        Import-Module $script:CorePsm1 -Force
    }
}

Describe "FindObject E2E Test Suite" -Tags "E2E" {

    AfterEach {
        # Ensure config session defaults are restored if altered
        Set-FindObjectConfig -Mode Contains -Property 'Name' -ErrorAction SilentlyContinue | Out-Null
    }

    # =========================================================================
    # TIER 1: FEATURE COVERAGE (F1 to F12)
    # =========================================================================
    Context "Tier 1: Feature Coverage" -Tags "Tier1" {

        # --- F1: Quoted Phrase Preservation ---
        Context "F1: Quoted Phrase Preservation" {
            It "F1-1: Preserves double-quoted multi-word phrase intact" {
                $items = @(
                    [PSCustomObject]@{ Name = "Google Chrome Setup" }
                    [PSCustomObject]@{ Name = "Google Browser Setup" }
                    [PSCustomObject]@{ Name = "Chrome Extension Host" }
                )
                $res = @($items | Find-ObjectByName '"Google Chrome"')
                $res.Count | Should -Be 1
                $res[0].Name | Should -Be "Google Chrome Setup"
            }

            It "F1-2: Preserves single-quoted multi-word phrase intact" {
                $items = @(
                    [PSCustomObject]@{ Name = "Visual Studio Code" }
                    [PSCustomObject]@{ Name = "Visual Studio 2022" }
                    [PSCustomObject]@{ Name = "Source Code Editor" }
                )
                $res = @($items | Find-ObjectByName "'Visual Studio Code'")
                $res.Count | Should -Be 1
                $res[0].Name | Should -Be "Visual Studio Code"
            }

            It "F1-3: Treats boolean keywords inside quotes as literal text" {
                $items = @(
                    [PSCustomObject]@{ Name = "Apple and Banana Smoothie" }
                    [PSCustomObject]@{ Name = "Apple Pie" }
                    [PSCustomObject]@{ Name = "Banana Split" }
                )
                $res = @($items | Find-ObjectByName '"Apple and Banana"')
                $res.Count | Should -Be 1
                $res[0].Name | Should -Be "Apple and Banana Smoothie"
            }

            It "F1-4: Preserves phrases containing punctuation and version symbols" {
                $items = @(
                    [PSCustomObject]@{ Name = "Release v2.0.0 (Stable)" }
                    [PSCustomObject]@{ Name = "Release v2.0.0 (Beta)" }
                    [PSCustomObject]@{ Name = "Release v1.0.0 (Stable)" }
                )
                $res = @($items | Find-ObjectByName '"v2.0.0 (Stable)"')
                $res.Count | Should -Be 1
                $res[0].Name | Should -Be "Release v2.0.0 (Stable)"
            }

            It "F1-5: Quoted phrase combined with boolean operator preserved as discrete token" {
                $items = @(
                    [PSCustomObject]@{ Name = "Google Chrome Setup" }
                    [PSCustomObject]@{ Name = "Google Chrome Portable" }
                    [PSCustomObject]@{ Name = "Mozilla Firefox Setup" }
                )
                $res = @($items | Find-ObjectByName '"Google Chrome" AND Setup')
                $res.Count | Should -Be 1
                $res[0].Name | Should -Be "Google Chrome Setup"
            }
        }

        # --- F2: Boolean Operator Lexing ---
        Context "F2: Boolean Operator Lexing" {
            It "F2-1: Recognizes AND case-insensitively" {
                $items = @(
                    [PSCustomObject]@{ Name = "apple pie" }
                    [PSCustomObject]@{ Name = "apple tart" }
                )
                $res1 = @($items | Find-ObjectByName "apple AND pie")
                $res2 = @($items | Find-ObjectByName "apple and pie")
                $res3 = @($items | Find-ObjectByName "apple And pie")
                $res1.Count | Should -Be 1
                $res2.Count | Should -Be 1
                $res3.Count | Should -Be 1
            }

            It "F2-2: Recognizes OR case-insensitively" {
                $items = @(
                    [PSCustomObject]@{ Name = "apple pie" }
                    [PSCustomObject]@{ Name = "banana bread" }
                    [PSCustomObject]@{ Name = "cherry tart" }
                )
                $res1 = @($items | Find-ObjectByName "apple OR banana")
                $res2 = @($items | Find-ObjectByName "apple or banana")
                $res1.Count | Should -Be 2
                $res2.Count | Should -Be 2
            }

            It "F2-3: Array syntax with boolean operators matches natural language string" {
                $items = @(
                    [PSCustomObject]@{ Name = "apple pie" }
                    [PSCustomObject]@{ Name = "cherry tart" }
                )
                $resArray = @($items | Find-ObjectByName @("apple", "OR", "cherry"))
                $resString = @($items | Find-ObjectByName "apple OR cherry")
                $resArray.Count | Should -Be 2
                $resString.Count | Should -Be 2
            }

            It "F2-4: Words containing operator substrings are treated as literals" {
                $items = @(
                    [PSCustomObject]@{ Name = "BAND_LEADER" }
                    [PSCustomObject]@{ Name = "STAND_ALONE" }
                    [PSCustomObject]@{ Name = "NOTIFY_SERVICE" }
                    [PSCustomObject]@{ Name = "TORNADO_WATCH" }
                )
                $res1 = @($items | Find-ObjectByName "BAND")
                $res2 = @($items | Find-ObjectByName "NOTIFY")
                $res1.Count | Should -Be 1
                $res1[0].Name | Should -Be "BAND_LEADER"
                $res2.Count | Should -Be 1
                $res2[0].Name | Should -Be "NOTIFY_SERVICE"
            }

            It "F2-5: Multiple internal spaces around operators are handled cleanly" {
                $items = @(
                    [PSCustomObject]@{ Name = "alpha beta gamma" }
                    [PSCustomObject]@{ Name = "alpha delta" }
                )
                $res = @($items | Find-ObjectByName "alpha AND gamma")
                $res.Count | Should -Be 1
                $res[0].Name | Should -Be "alpha beta gamma"
            }
        }

        # --- F3: Boolean Operator Precedence ---
        Context "F3: Boolean Operator Precedence" {
            It "F3-1: Enforces NOT > AND > OR for A OR B AND C" {
                # A OR (B AND C):
                # item1: A=True, B=False, C=False -> True
                # item2: A=False, B=True, C=True -> True
                # item3: A=False, B=True, C=False -> False (under naive left-to-right (A OR B) AND C, item1 would be False!)
                $items = @(
                    [PSCustomObject]@{ Name = "alpha" }
                    [PSCustomObject]@{ Name = "beta gamma" }
                    [PSCustomObject]@{ Name = "beta only" }
                )
                $res = @($items | Find-ObjectByName "alpha OR beta AND gamma")
                $res.Count | Should -Be 2
                $names = $res | ForEach-Object { $_.Name }
                $names | Should -Contain "alpha"
                $names | Should -Contain "beta gamma"
                $names | Should -Not -Contain "beta only"
            }

            It "F3-2: Precedence for A AND B OR C AND D evaluates as (A AND B) OR (C AND D)" {
                $items = @(
                    [PSCustomObject]@{ Name = "prod web" }
                    [PSCustomObject]@{ Name = "dev db" }
                    [PSCustomObject]@{ Name = "prod db" }
                    [PSCustomObject]@{ Name = "dev web" }
                )
                $res = @($items | Find-ObjectByName "prod AND web OR dev AND db")
                $res.Count | Should -Be 2
                $names = $res | ForEach-Object { $_.Name }
                $names | Should -Contain "prod web"
                $names | Should -Contain "dev db"
            }

            It "F3-3: NOT binds tighter than AND: NOT A AND B evaluates as (NOT A) AND B" {
                $items = @(
                    [PSCustomObject]@{ Name = "beta" }
                    [PSCustomObject]@{ Name = "alpha beta" }
                    [PSCustomObject]@{ Name = "alpha" }
                )
                $res = @($items | Find-ObjectByName "NOT alpha AND beta")
                $res.Count | Should -Be 1
                $res[0].Name | Should -Be "beta"
            }

            It "F3-4: NOT binds tighter than OR: A OR NOT B" {
                $items = @(
                    [PSCustomObject]@{ Name = "apple" }
                    [PSCustomObject]@{ Name = "banana" }
                    [PSCustomObject]@{ Name = "cherry" }
                )
                # Matches anything with apple, OR anything NOT containing banana (cherry has no banana -> matches)
                $res = @($items | Find-ObjectByName "apple OR NOT banana")
                $names = $res | ForEach-Object { $_.Name }
                $names | Should -Contain "apple"
                $names | Should -Contain "cherry"
                $names | Should -Not -Contain "banana"
            }

            It "F3-5: Mixed chain: A OR B AND NOT C" {
                $items = @(
                    [PSCustomObject]@{ Name = "first" }
                    [PSCustomObject]@{ Name = "second active" }
                    [PSCustomObject]@{ Name = "second inactive" }
                )
                # first matches; second active matches; second inactive rejected by NOT inactive
                $res = @($items | Find-ObjectByName "first OR second AND NOT inactive")
                $res.Count | Should -Be 2
                $names = $res | ForEach-Object { $_.Name }
                $names | Should -Contain "first"
                $names | Should -Contain "second active"
            }
        }

        # --- F4: Expression Grouping ---
        Context "F4: Expression Grouping" {
            It "F4-1: Parentheses override precedence: (A OR B) AND C" {
                $items = @(
                    [PSCustomObject]@{ Name = "apple pie" }
                    [PSCustomObject]@{ Name = "cherry pie" }
                    [PSCustomObject]@{ Name = "apple tart" }
                    [PSCustomObject]@{ Name = "banana bread" }
                )
                $res = @($items | Find-ObjectByName "(apple OR cherry) AND pie")
                $res.Count | Should -Be 2
                $names = $res | ForEach-Object { $_.Name }
                $names | Should -Contain "apple pie"
                $names | Should -Contain "cherry pie"
                $names | Should -Not -Contain "apple tart"
            }

            It "F4-2: Nested parentheses evaluate innermost first" {
                $items = @(
                    [PSCustomObject]@{ Name = "apple sweet red" }
                    [PSCustomObject]@{ Name = "banana sweet yellow" }
                    [PSCustomObject]@{ Name = "lemon sour yellow" }
                    [PSCustomObject]@{ Name = "grape tart purple" }
                )
                $res = @($items | Find-ObjectByName "((apple OR banana) AND sweet) OR lemon")
                $res.Count | Should -Be 3
                $names = $res | ForEach-Object { $_.Name }
                $names | Should -Contain "apple sweet red"
                $names | Should -Contain "banana sweet yellow"
                $names | Should -Contain "lemon sour yellow"
                $names | Should -Not -Contain "grape tart purple"
            }

            It "F4-3: Parentheses enclosing quoted phrases" {
                $items = @(
                    [PSCustomObject]@{ Name = "Google Chrome 120" }
                    [PSCustomObject]@{ Name = "Mozilla Firefox 120" }
                    [PSCustomObject]@{ Name = "Google Chrome 119" }
                )
                $res = @($items | Find-ObjectByName '("Google Chrome" OR "Mozilla Firefox") AND 120')
                $res.Count | Should -Be 2
                $names = $res | ForEach-Object { $_.Name }
                $names | Should -Contain "Google Chrome 120"
                $names | Should -Contain "Mozilla Firefox 120"
            }

            It "F4-4: Grouping with negation: NOT (A OR B)" {
                $items = @(
                    [PSCustomObject]@{ Name = "prod server" }
                    [PSCustomObject]@{ Name = "dev server" }
                    [PSCustomObject]@{ Name = "test server" }
                    [PSCustomObject]@{ Name = "stg server" }
                )
                $res = @($items | Find-ObjectByName "NOT (dev OR test)")
                $res.Count | Should -Be 2
                $names = $res | ForEach-Object { $_.Name }
                $names | Should -Contain "prod server"
                $names | Should -Contain "stg server"
            }

            It "F4-5: Multiple disjoint parenthesized groups: (A OR B) AND (C OR D)" {
                $items = @(
                    [PSCustomObject]@{ Name = "alpha gamma" }
                    [PSCustomObject]@{ Name = "alpha delta" }
                    [PSCustomObject]@{ Name = "beta gamma" }
                    [PSCustomObject]@{ Name = "alpha epsilon" }
                )
                $res = @($items | Find-ObjectByName "(alpha OR beta) AND (gamma OR delta)")
                $res.Count | Should -Be 3
                $names = $res | ForEach-Object { $_.Name }
                $names | Should -Contain "alpha gamma"
                $names | Should -Contain "alpha delta"
                $names | Should -Contain "beta gamma"
                $names | Should -Not -Contain "alpha epsilon"
            }
        }

        # --- F5: Unary NOT Evaluation ---
        Context "F5: Unary NOT Evaluation" {
            It "F5-1: Leading unary NOT filters matching objects" {
                $items = @(
                    [PSCustomObject]@{ Name = "chrome" }
                    [PSCustomObject]@{ Name = "chrome helper" }
                    [PSCustomObject]@{ Name = "firefox" }
                )
                $res = @($items | Find-ObjectByName "NOT helper")
                $res.Count | Should -Be 2
                $names = $res | ForEach-Object { $_.Name }
                $names | Should -Contain "chrome"
                $names | Should -Contain "firefox"
                $names | Should -Not -Contain "chrome helper"
            }

            It "F5-2: Unary NOT in conjunction: A AND NOT B" {
                $items = @(
                    [PSCustomObject]@{ Name = "apple pie" }
                    [PSCustomObject]@{ Name = "cherry pie" }
                    [PSCustomObject]@{ Name = "apple tart" }
                )
                $res = @($items | Find-ObjectByName "pie AND NOT cherry")
                $res.Count | Should -Be 1
                $res[0].Name | Should -Be "apple pie"
            }

            It "F5-3: Unary NOT in disjunction: A OR NOT B" {
                $items = @(
                    [PSCustomObject]@{ Name = "primary" }
                    [PSCustomObject]@{ Name = "backup active" }
                    [PSCustomObject]@{ Name = "backup idle" }
                )
                $res = @($items | Find-ObjectByName "primary OR NOT idle")
                $res.Count | Should -Be 2
                $names = $res | ForEach-Object { $_.Name }
                $names | Should -Contain "primary"
                $names | Should -Contain "backup active"
            }

            It "F5-4: Conjunction of multiple NOT clauses: NOT dev AND NOT stg" {
                $items = @(
                    [PSCustomObject]@{ Name = "prod" }
                    [PSCustomObject]@{ Name = "dev" }
                    [PSCustomObject]@{ Name = "stg" }
                )
                $res = @($items | Find-ObjectByName "NOT dev AND NOT stg")
                $res.Count | Should -Be 1
                $res[0].Name | Should -Be "prod"
            }

            It "F5-5: Unary NOT targeted with -Property" {
                $items = @(
                    [PSCustomObject]@{ Title = "Manager"; Role = "Admin" }
                    [PSCustomObject]@{ Title = "Engineer"; Role = "User" }
                    [PSCustomObject]@{ Title = "Lead"; Role = "Admin" }
                )
                $res = @($items | Find-ObjectByName "NOT Admin" -Property Role)
                $res.Count | Should -Be 1
                $res[0].Title | Should -Be "Engineer"
            }
        }

        # --- F6: Dotted Property Paths ---
        Context "F6: Dotted Property Paths" {
            It "F6-1: Resolves 2-level dotted property path (Parent.Child)" {
                $items = @(
                    [PSCustomObject]@{ Server = [PSCustomObject]@{ Hostname = "db-01.internal" } }
                    [PSCustomObject]@{ Server = [PSCustomObject]@{ Hostname = "web-01.internal" } }
                )
                $res = @($items | Find-ObjectByName "db-01" -Property "Server.Hostname")
                $res.Count | Should -Be 1
                $res[0].Server.Hostname | Should -Be "db-01.internal"
            }

            It "F6-2: Resolves 3-level dotted property path (A.B.C)" {
                $items = @(
                    [PSCustomObject]@{ Org = [PSCustomObject]@{ Team = [PSCustomObject]@{ Lead = "Alice" } } }
                    [PSCustomObject]@{ Org = [PSCustomObject]@{ Team = [PSCustomObject]@{ Lead = "Bob" } } }
                )
                $res = @($items | Find-ObjectByName "Alice" -Property "Org.Team.Lead")
                $res.Count | Should -Be 1
                $res[0].Org.Team.Lead | Should -Be "Alice"
            }

            It "F6-3: Unwraps collections in dotted paths (Items.Name)" {
                $items = @(
                    [PSCustomObject]@{
                        GroupId = 101
                        Members = @(
                            [PSCustomObject]@{ Username = "jsmith" }
                            [PSCustomObject]@{ Username = "asmith" }
                        )
                    }
                    [PSCustomObject]@{
                        GroupId = 102
                        Members = @(
                            [PSCustomObject]@{ Username = "bwhite" }
                        )
                    }
                )
                $res = @($items | Find-ObjectByName "asmith" -Property "Members.Username")
                $res.Count | Should -Be 1
                $res[0].GroupId | Should -Be 101
            }

            It "F6-4: Missing intermediate property returns empty without error" {
                $items = @(
                    [PSCustomObject]@{ Config = $null }
                    [PSCustomObject]@{ Other = "Val" }
                )
                { $script:res = @($items | Find-ObjectByName "Target" -Property "Config.Setting.Name") } | Should -Not -Throw
                $script:res.Count | Should -Be 0
            }

            It "F6-5: Falls back to literal property if property name itself contains dots" {
                $obj = [PSCustomObject]@{ "System.Core.Version" = "5.1.0" }
                $res = @($obj | Find-ObjectByName "5.1.0" -Property "System.Core.Version")
                $res.Count | Should -Be 1
            }
        }

        # --- F7: Wildcard Non-String Inspection ---
        Context "F7: Wildcard Non-String Inspection" {
            It "F7-1: -Property * inspects integer properties without dropping" {
                $items = @(
                    [PSCustomObject]@{ Name = "WebSvc"; Port = 8080 }
                    [PSCustomObject]@{ Name = "DbSvc"; Port = 5432 }
                )
                $res = @($items | Find-ObjectByName "8080" -Property *)
                $res.Count | Should -Be 1
                $res[0].Name | Should -Be "WebSvc"
            }

            It "F7-2: -Property * inspects DateTime properties" {
                $date1 = [datetime]"2026-05-15T12:00:00"
                $date2 = [datetime]"2024-01-01T08:00:00"
                $items = @(
                    [PSCustomObject]@{ Name = "BackupA"; CreatedAt = $date1 }
                    [PSCustomObject]@{ Name = "BackupB"; CreatedAt = $date2 }
                )
                $res = @($items | Find-ObjectByName "2026" -Property *)
                $res.Count | Should -Be 1
                $res[0].Name | Should -Be "BackupA"
            }

            It "F7-3: -Property * inspects Boolean properties" {
                $items = @(
                    [PSCustomObject]@{ Name = "FeatureA"; IsEnabled = $true }
                    [PSCustomObject]@{ Name = "FeatureB"; IsEnabled = $false }
                )
                $res = @($items | Find-ObjectByName "True" -Property *)
                $res.Count | Should -Be 1
                $res[0].Name | Should -Be "FeatureA"
            }

            It "F7-4: -Property * inspects Guid properties" {
                $guidTarget = [guid]::Parse("12345678-aaaa-bbbb-cccc-111122223333")
                $guidOther  = [guid]::Parse("99999999-0000-0000-0000-999999999999")
                $items = @(
                    [PSCustomObject]@{ Name = "ObjA"; Id = $guidTarget }
                    [PSCustomObject]@{ Name = "ObjB"; Id = $guidOther }
                )
                $res = @($items | Find-ObjectByName "12345678" -Property *)
                $res.Count | Should -Be 1
                $res[0].Name | Should -Be "ObjA"
            }

            It "F7-5: -Property * inspects mixed PSCustomObject across diverse property types" {
                $items = @(
                    [PSCustomObject]@{
                        Host = "srv-app-01"
                        Port = 443
                        Active = $true
                        Score = 98.6
                    }
                    [PSCustomObject]@{
                        Host = "srv-app-02"
                        Port = 80
                        Active = $false
                        Score = 45.2
                    }
                )
                $res = @($items | Find-ObjectByName "98.6" -Property *)
                $res.Count | Should -Be 1
                $res[0].Host | Should -Be "srv-app-01"
            }
        }

        # --- F8: Array Element Evaluation ---
        Context "F8: Array Element Evaluation" {
            It "F8-1: Evaluates individual array elements in Exact mode" {
                $items = @(
                    [PSCustomObject]@{ Name = "SvcA"; Tags = @("production", "pci") }
                    [PSCustomObject]@{ Name = "SvcB"; Tags = @("staging", "internal") }
                )
                $res = @($items | Find-ObjectByName "production" -Property Tags -Mode Exact)
                $res.Count | Should -Be 1
                $res[0].Name | Should -Be "SvcA"
            }

            It "F8-2: Rejects concatenated multi-element strings in Exact mode" {
                $items = @(
                    [PSCustomObject]@{ Name = "SvcA"; Tags = @("production", "pci") }
                )
                # If flattened destructively to "production pci", exact match would fail
                $res = @($items | Find-ObjectByName "production pci" -Property Tags -Mode Exact)
                $res.Count | Should -Be 0
            }

            It "F8-3: Evaluates individual array elements in StartsWith mode" {
                $items = @(
                    [PSCustomObject]@{ Name = "PkgA"; Dependencies = @("System.Text.Json", "Microsoft.Extensions") }
                    [PSCustomObject]@{ Name = "PkgB"; Dependencies = @("Newtonsoft.Json", "NUnit") }
                )
                $res = @($items | Find-ObjectByName "System" -Property Dependencies -Mode StartsWith)
                $res.Count | Should -Be 1
                $res[0].Name | Should -Be "PkgA"
            }

            It "F8-4: Prevents cross-element boundary substring leakage" {
                $items = @(
                    [PSCustomObject]@{ Name = "Item1"; Tags = @("alpha", "beta") }
                )
                # If flattened to "alphabeta", searching "habe" in Contains mode would erroneously match
                $res = @($items | Find-ObjectByName "habe" -Property Tags -Mode Contains)
                $res.Count | Should -Be 0
            }

            It "F8-5: Evaluates array containing numeric items" {
                $items = @(
                    [PSCustomObject]@{ Id = "A"; StatusCodes = @(200, 204, 301) }
                    [PSCustomObject]@{ Id = "B"; StatusCodes = @(400, 404, 500) }
                )
                $res = @($items | Find-ObjectByName "204" -Property StatusCodes -Mode Exact)
                $res.Count | Should -Be 1
                $res[0].Id | Should -Be "A"
            }
        }

        # --- F9: Regex Pipeline Resilience ---
        Context "F9: Regex Pipeline Resilience" {
            It "F9-1: Emits terminating error on invalid regex syntax before pipeline streaming" {
                $data = 1..50 | ForEach-Object { [PSCustomObject]@{ Name = "item$_" } }
                { @($data | Find-ObjectByName "[" -Mode Regex) } | Should -Throw
            }

            It "F9-2: Halts immediately on invalid regex quantifier without emitting items" {
                $items = @(
                    [PSCustomObject]@{ Name = "valid1" }
                    [PSCustomObject]@{ Name = "valid2" }
                )
                { @($items | Find-ObjectByName "+abc" -Mode Regex) } | Should -Throw
            }

            It "F9-3: Matches valid .NET regex patterns with character classes" {
                $items = @(
                    [PSCustomObject]@{ Name = "audit_2026_09_13.log" }
                    [PSCustomObject]@{ Name = "audit_report.docx" }
                )
                $res = @($items | Find-ObjectByName 'audit_\d{4}_\d{2}_\d{2}\.log' -Mode Regex)
                $res.Count | Should -Be 1
                $res[0].Name | Should -Be "audit_2026_09_13.log"
            }

            It "F9-4: Regex mode respects -CaseSensitive" {
                $items = @(
                    [PSCustomObject]@{ Name = "ERROR_EVENT" }
                    [PSCustomObject]@{ Name = "error_event" }
                )
                $res = @($items | Find-ObjectByName "^ERROR" -Mode Regex -CaseSensitive)
                $res.Count | Should -Be 1
                $res[0].Name | Should -Be "ERROR_EVENT"
            }

            It "F9-5: Invalid regex in boolean clause terminates cleanly in begin" {
                $items = @([PSCustomObject]@{ Name = "test" })
                { @($items | Find-ObjectByName "valid AND [unclosed" -Mode Regex) } | Should -Throw
            }
        }

        # --- F10: Clean Highlight Pipeline ---
        Context "F10: Clean Highlight Pipeline" {
            It "F10-1: -Highlight emits objects via Success stream without Write-Host pollution" {
                $infoStream = [System.Collections.ArrayList]::new()
                $obj = [PSCustomObject]@{ Name = "Production Server" }
                $res = @($obj | Find-ObjectByName "Server" -Highlight -InformationAction Continue -InformationVariable infoStream)
                $res.Count | Should -Be 1
                # Must not write raw lines to Information/Host stream
                $infoStream.Count | Should -Be 0
            }

            It "F10-2: -Highlight passes object cleanly through to Format-Table" {
                $items = @(
                    [PSCustomObject]@{ Name = "TestApp"; Status = "Running" }
                )
                $table = $null
                { $script:table = $items | Find-ObjectByName "TestApp" -Highlight | Format-Table | Out-String } | Should -Not -Throw
                $script:table | Should -Not -BeNullOrEmpty
            }

            It "F10-3: Highlighted property contains ANSI escape formatting sequence" {
                $obj = [PSCustomObject]@{ Name = "HighlightTarget" }
                $res = @($obj | Find-ObjectByName "Target" -Highlight)
                $res.Count | Should -Be 1
                # ANSI ESC is [char]27: \e[1;33m
                $esc = [char]27
                $res[0].Name | Should -Match ([regex]::Escape("${esc}[1;33m"))
            }

            It "F10-4: Capturing highlighted pipeline output in variable preserves object" {
                $items = @(
                    [PSCustomObject]@{ Name = "WorkerNode1" }
                    [PSCustomObject]@{ Name = "MasterNode1" }
                )
                $captured = @($items | Find-ObjectByName "Worker" -Highlight)
                $captured.Count | Should -Be 1
                $captured[0] | Should -Not -BeNullOrEmpty
            }

            It "F10-5: Highlighting handles multiple occurrences within target property" {
                $obj = [PSCustomObject]@{ Name = "echo echo echo" }
                $res = @($obj | Find-ObjectByName "echo" -Highlight)
                $res.Count | Should -Be 1
                $esc = [char]27
                $matches = [regex]::Matches($res[0].Name, [regex]::Escape("${esc}[1;33m"))
                $matches.Count | Should -Be 3
            }
        }

        # --- F11: Intune Submodule Extraction ---
        Context "F11: Intune Submodule Extraction" {
            It "F11-1: Submodule manifest FindObject.Intune.psd1 exists" {
                Test-Path $script:IntuneManifest | Should -BeTrue
            }

            It "F11-2: Submodule script FindObject.Intune.psm1 exists" {
                Test-Path $script:IntunePsm1 | Should -BeTrue
            }

            It "F11-3: Submodule exports all 8 Intune cmdlets" {
                if (-not (Test-Path $script:IntuneManifest)) {
                    Test-Path $script:IntuneManifest | Should -BeTrue
                } else {
                    $manifest = Import-PowerShellDataFile $script:IntuneManifest
                    $expected = @(
                        'Connect-FindObjectGraph', 'Disconnect-FindObjectGraph',
                        'Get-IntuneDevice', 'Get-IntuneApp', 'Get-IntuneCompliancePolicy',
                        'Get-IntuneConfigProfile', 'Get-IntuneAutopilotDevice', 'Get-IntuneEnrollment'
                    )
                    foreach ($cmd in $expected) {
                        $manifest.FunctionsToExport | Should -Contain $cmd
                    }
                }
            }

            It "F11-4: Submodule exports gid alias for Get-IntuneDevice" {
                if (-not (Test-Path $script:IntuneManifest)) {
                    Test-Path $script:IntuneManifest | Should -BeTrue
                } else {
                    $manifest = Import-PowerShellDataFile $script:IntuneManifest
                    $manifest.AliasesToExport | Should -Contain 'gid'
                }
            }

            It "F11-5: Get-IntuneDevice raises auth guard exception when disconnected" {
                if (-not (Test-Path $script:IntunePsm1)) {
                    Test-Path $script:IntunePsm1 | Should -BeTrue
                } else {
                    Import-Module $script:IntunePsm1 -Force
                    Disconnect-FindObjectGraph -ErrorAction SilentlyContinue
                    { Get-IntuneDevice } | Should -Throw "*Connect-FindObjectGraph*"
                }
            }
        }

        # --- F12: Core Module Isolation ---
        Context "F12: Core Module Isolation" {
            It "F12-1: Core manifest exports exactly 3 core functions" {
                $manifest = Import-PowerShellDataFile $script:CoreManifest
                $manifest.FunctionsToExport.Count | Should -Be 3
                $manifest.FunctionsToExport | Should -Contain 'Find-ObjectByName'
                $manifest.FunctionsToExport | Should -Contain 'Get-FindObjectConfig'
                $manifest.FunctionsToExport | Should -Contain 'Set-FindObjectConfig'
            }

            It "F12-2: Core manifest exports 0 Intune cmdlets" {
                $manifest = Import-PowerShellDataFile $script:CoreManifest
                $intuneCmds = @($manifest.FunctionsToExport | Where-Object { $_ -like 'Get-Intune*' -or $_ -like '*-FindObjectGraph' })
                $intuneCmds.Count | Should -Be 0
            }

            It "F12-3: Core manifest exports fob alias and 0 Intune aliases" {
                $manifest = Import-PowerShellDataFile $script:CoreManifest
                $manifest.AliasesToExport | Should -Contain 'fob'
                $manifest.AliasesToExport | Should -Not -Contain 'gid'
            }

            It "F12-4: Core engine FindObject.psm1 contains 0 direct Microsoft Graph endpoint URIs" {
                $content = Get-Content -LiteralPath $script:CorePsm1 -Raw
                $content | Should -Not -Match 'https://graph\.microsoft\.com'
            }

            It "F12-5: Core module operates completely standalone without Intune dependencies" {
                Import-Module $script:CoreManifest -Force
                $res = [PSCustomObject]@{ Name = "IsolatedCoreTest" } | fob "Isolated"
                $res.Name | Should -Be "IsolatedCoreTest"
            }
        }
    }

    # =========================================================================
    # TIER 2: BOUNDARY & CORNER CASES (F1 to F12)
    # =========================================================================
    Context "Tier 2: Boundary & Corner Cases" -Tags "Tier2" {

        # --- F1 Boundary ---
        Context "F1: Quoted Phrase Boundaries" {
            It "T2-F1-1: Empty double quotes in query handled gracefully" {
                $items = @([PSCustomObject]@{ Name = "test item" })
                { $script:res = @($items | Find-ObjectByName '"" test') } | Should -Not -Throw
                $script:res.Count | Should -Be 1
            }

            It "T2-F1-2: Whitespace-only quotes in query handled gracefully" {
                $items = @([PSCustomObject]@{ Name = "test item" })
                { $script:res = @($items | Find-ObjectByName '" " test') } | Should -Not -Throw
                $script:res.Count | Should -Be 1
            }

            It "T2-F1-3: Unclosed quote throws descriptive syntax error" {
                $items = @([PSCustomObject]@{ Name = "test item" })
                { @($items | Find-ObjectByName '"unclosed phrase') } | Should -Throw
            }

            It "T2-F1-4: Adjacent quoted phrases parsed as two distinct phrases" {
                $items = @(
                    [PSCustomObject]@{ Name = "Alpha Beta Gamma Delta" }
                    [PSCustomObject]@{ Name = "Alpha Gamma" }
                )
                $res = @($items | Find-ObjectByName '"Alpha Beta" "Gamma Delta"')
                $res.Count | Should -Be 1
                $res[0].Name | Should -Be "Alpha Beta Gamma Delta"
            }

            It "T2-F1-5: Quoted phrase at extreme string boundaries (start and end)" {
                $items = @(
                    [PSCustomObject]@{ Name = "start middle end" }
                )
                $res1 = @($items | Find-ObjectByName '"start middle"')
                $res2 = @($items | Find-ObjectByName '"middle end"')
                $res1.Count | Should -Be 1
                $res2.Count | Should -Be 1
            }
        }

        # --- F2 Boundary ---
        Context "F2: Boolean Operator Lexing Boundaries" {
            It "T2-F2-1: Trailing boolean operator throws syntax error" {
                $items = @([PSCustomObject]@{ Name = "apple" })
                { @($items | Find-ObjectByName "apple AND") } | Should -Throw
            }

            It "T2-F2-2: Leading binary operator throws syntax error" {
                $items = @([PSCustomObject]@{ Name = "banana" })
                { @($items | Find-ObjectByName "OR banana") } | Should -Throw
            }

            It "T2-F2-3: Consecutive binary operators throw syntax error" {
                $items = @([PSCustomObject]@{ Name = "cherry" })
                { @($items | Find-ObjectByName "apple AND OR banana") } | Should -Throw
            }

            It "T2-F2-4: Operator-only input string throws descriptive error" {
                $items = @([PSCustomObject]@{ Name = "something" })
                { @($items | Find-ObjectByName "AND OR NOT") } | Should -Throw
            }

            It "T2-F2-5: Mixed case boolean permutations (aNd, oR, nOt)" {
                $items = @(
                    [PSCustomObject]@{ Name = "alpha beta" }
                    [PSCustomObject]@{ Name = "gamma" }
                )
                $res = @($items | Find-ObjectByName "alpha aNd beta oR nOt gamma")
                $res.Count | Should -Be 1
                $res[0].Name | Should -Be "alpha beta"
            }
        }

        # --- F3 Boundary ---
        Context "F3: Boolean Precedence Boundaries" {
            It "T2-F3-1: Long 6-term unparenthesized chain respects precedence" {
                # A OR B AND C OR D AND E OR F
                # (A) OR (B AND C) OR (D AND E) OR (F)
                $items = @(
                    [PSCustomObject]@{ Name = "A" }
                    [PSCustomObject]@{ Name = "B C" }
                    [PSCustomObject]@{ Name = "D E" }
                    [PSCustomObject]@{ Name = "F" }
                    [PSCustomObject]@{ Name = "B only" }
                    [PSCustomObject]@{ Name = "D only" }
                )
                $res = @($items | Find-ObjectByName "A OR B AND C OR D AND E OR F")
                $res.Count | Should -Be 4
                $names = $res | ForEach-Object { $_.Name }
                $names | Should -Contain "A"
                $names | Should -Contain "B C"
                $names | Should -Contain "D E"
                $names | Should -Contain "F"
                $names | Should -Not -Contain "B only"
            }

            It "T2-F3-2: Contradictory condition (A AND NOT A) returns empty set" {
                $items = @(
                    [PSCustomObject]@{ Name = "item" }
                    [PSCustomObject]@{ Name = "item other" }
                )
                $res = @($items | Find-ObjectByName "item AND NOT item")
                $res.Count | Should -Be 0
            }

            It "T2-F3-3: Double negation (NOT NOT A) evaluates to A" {
                $items = @(
                    [PSCustomObject]@{ Name = "target" }
                    [PSCustomObject]@{ Name = "other" }
                )
                $res = @($items | Find-ObjectByName "NOT NOT target")
                $res.Count | Should -Be 1
                $res[0].Name | Should -Be "target"
            }

            It "T2-F3-4: Idempotent AND conjunction (A AND A AND A) matches A" {
                $items = @(
                    [PSCustomObject]@{ Name = "target" }
                    [PSCustomObject]@{ Name = "other" }
                )
                $res = @($items | Find-ObjectByName "target AND target AND target")
                $res.Count | Should -Be 1
                $res[0].Name | Should -Be "target"
            }

            It "T2-F3-5: Idempotent OR disjunction (A OR A OR A) matches A" {
                $items = @(
                    [PSCustomObject]@{ Name = "target" }
                    [PSCustomObject]@{ Name = "other" }
                )
                $res = @($items | Find-ObjectByName "target OR target OR target")
                $res.Count | Should -Be 1
                $res[0].Name | Should -Be "target"
            }
        }

        # --- F4 Boundary ---
        Context "F4: Grouping Boundaries" {
            It "T2-F4-1: 5-level deeply nested parentheses evaluate accurately" {
                $items = @(
                    [PSCustomObject]@{ Name = "deep target" }
                    [PSCustomObject]@{ Name = "other" }
                )
                $res = @($items | Find-ObjectByName "(((((target)))))")
                $res.Count | Should -Be 1
                $res[0].Name | Should -Be "deep target"
            }

            It "T2-F4-2: Empty parentheses () throw syntax error" {
                $items = @([PSCustomObject]@{ Name = "test" })
                { @($items | Find-ObjectByName "apple AND ()") } | Should -Throw
            }

            It "T2-F4-3: Unclosed opening parenthesis throws syntax error" {
                $items = @([PSCustomObject]@{ Name = "test" })
                { @($items | Find-ObjectByName "(apple OR banana") } | Should -Throw
            }

            It "T2-F4-4: Stray closing parenthesis throws syntax error" {
                $items = @([PSCustomObject]@{ Name = "test" })
                { @($items | Find-ObjectByName "apple OR banana)") } | Should -Throw
            }

            It "T2-F4-5: Parentheses enclosing operator only throw syntax error" {
                $items = @([PSCustomObject]@{ Name = "test" })
                { @($items | Find-ObjectByName "apple AND (OR) banana") } | Should -Throw
            }
        }

        # --- F5 Boundary ---
        Context "F5: Unary NOT Boundaries" {
            It "T2-F5-1: Triple negation (NOT NOT NOT A) evaluates to NOT A" {
                $items = @(
                    [PSCustomObject]@{ Name = "match_me" }
                    [PSCustomObject]@{ Name = "exclude_me" }
                )
                $res = @($items | Find-ObjectByName "NOT NOT NOT exclude_me")
                $res.Count | Should -Be 1
                $res[0].Name | Should -Be "match_me"
            }

            It "T2-F5-2: Unary NOT on non-matching keyword matches all non-empty items" {
                $items = @(
                    [PSCustomObject]@{ Name = "alpha" }
                    [PSCustomObject]@{ Name = "beta" }
                )
                $res = @($items | Find-ObjectByName "NOT nonexistent")
                $res.Count | Should -Be 2
            }

            It "T2-F5-3: Trailing NOT without operand throws syntax error" {
                $items = @([PSCustomObject]@{ Name = "apple" })
                { @($items | Find-ObjectByName "apple NOT") } | Should -Throw
            }

            It "T2-F5-4: NOT against null property value skips null without throwing" {
                $items = @(
                    [PSCustomObject]@{ Name = $null }
                    [PSCustomObject]@{ Name = "valid" }
                )
                { $script:res = @($items | Find-ObjectByName "NOT test") } | Should -Not -Throw
                $script:res.Count | Should -Be 1
                $script:res[0].Name | Should -Be "valid"
            }

            It "T2-F5-5: NOT evaluating against whitespace-only target values" {
                $items = @(
                    [PSCustomObject]@{ Name = " " }
                    [PSCustomObject]@{ Name = "content" }
                )
                $res = @($items | Find-ObjectByName "NOT target")
                $res.Count | Should -Be 1
                $res[0].Name | Should -Be "content"
            }
        }

        # --- F6 Boundary ---
        Context "F6: Dotted Property Path Boundaries" {
            It "T2-F6-1: 10-level deep property traversal" {
                $root = [PSCustomObject]@{ L1 = [PSCustomObject]@{ L2 = [PSCustomObject]@{ L3 = [PSCustomObject]@{ L4 = [PSCustomObject]@{ L5 = [PSCustomObject]@{ L6 = [PSCustomObject]@{ L7 = [PSCustomObject]@{ L8 = [PSCustomObject]@{ L9 = [PSCustomObject]@{ Leaf = "DeepMatch" } } } } } } } } } }
                $res = @($root | Find-ObjectByName "DeepMatch" -Property "L1.L2.L3.L4.L5.L6.L7.L8.L9.Leaf")
                $res.Count | Should -Be 1
            }

            It "T2-F6-2: Property path ending with dot handled gracefully" {
                $obj = [PSCustomObject]@{ Server = [PSCustomObject]@{ Name = "db1" } }
                { $res = @($obj | Find-ObjectByName "db1" -Property "Server.Name.") } | Should -Not -Throw
            }

            It "T2-F6-3: Property path starting with dot handled gracefully" {
                $obj = [PSCustomObject]@{ Server = [PSCustomObject]@{ Name = "db1" } }
                { $res = @($obj | Find-ObjectByName "db1" -Property ".Server.Name") } | Should -Not -Throw
            }

            It "T2-F6-4: Dotted path traversing into primitive type does not throw" {
                $obj = [PSCustomObject]@{ Count = 42 }
                { $script:res = @($obj | Find-ObjectByName "test" -Property "Count.NonExistent.Deep") } | Should -Not -Throw
                $script:res.Count | Should -Be 0
            }

            It "T2-F6-5: Dotted path on objects with special-character property names" {
                $obj = [PSCustomObject]@{
                    "@odata.context" = "https://example.com"
                    "meta.custom"    = "special_val"
                }
                $res = @($obj | Find-ObjectByName "special_val" -Property "meta.custom")
                $res.Count | Should -Be 1
            }
        }

        # --- F7 Boundary ---
        Context "F7: Wildcard Non-String Inspection Boundaries" {
            It "T2-F7-1: Object with 0 properties handled without throwing" {
                $emptyObj = [PSCustomObject]@{}
                { $script:res = @($emptyObj | Find-ObjectByName "anything" -Property *) } | Should -Not -Throw
                $script:res.Count | Should -Be 0
            }

            It "T2-F7-2: Object with all null properties handled without throwing" {
                $nullObj = [PSCustomObject]@{ P1 = $null; P2 = $null; P3 = $null }
                { $script:res = @($nullObj | Find-ObjectByName "anything" -Property *) } | Should -Not -Throw
                $script:res.Count | Should -Be 0
            }

            It "T2-F7-3: Object with 100 properties inspected accurately" {
                $hash = [ordered]@{}
                1..100 | ForEach-Object { $hash["Prop$_"] = "val$_" }
                $hash["TargetProp"] = "needle_in_haystack"
                $largeObj = [PSCustomObject]$hash

                $res = @($largeObj | Find-ObjectByName "needle_in_haystack" -Property *)
                $res.Count | Should -Be 1
            }

            It "T2-F7-4: Explicit boolean `$false` property inspected without dropping" {
                $obj = [PSCustomObject]@{ Name = "SecurityConfig"; Enforced = $false }
                $res = @($obj | Find-ObjectByName "False" -Property *)
                $res.Count | Should -Be 1
                $res[0].Name | Should -Be "SecurityConfig"
            }

            It "T2-F7-5: Numeric 0 property value inspected accurately" {
                $obj = [PSCustomObject]@{ Name = "Counter"; Retries = 0 }
                $res = @($obj | Find-ObjectByName "0" -Property * -Mode Exact)
                $res.Count | Should -Be 1
                $res[0].Name | Should -Be "Counter"
            }
        }

        # --- F8 Boundary ---
        Context "F8: Array Element Boundaries" {
            It "T2-F8-1: Empty array property handled cleanly" {
                $obj = [PSCustomObject]@{ Name = "Item"; Tags = @() }
                $res = @($obj | Find-ObjectByName "anything" -Property Tags)
                $res.Count | Should -Be 0
            }

            It "T2-F8-2: Single-element array property evaluated correctly" {
                $obj = [PSCustomObject]@{ Name = "Item"; Tags = @("single") }
                $res = @($obj | Find-ObjectByName "single" -Property Tags -Mode Exact)
                $res.Count | Should -Be 1
            }

            It "T2-F8-3: Array containing null elements skips nulls safely" {
                $obj = [PSCustomObject]@{ Name = "Item"; Tags = @($null, "valid", $null) }
                $res = @($obj | Find-ObjectByName "valid" -Property Tags -Mode Exact)
                $res.Count | Should -Be 1
            }

            It "T2-F8-4: Array containing nested arrays evaluated recursively or flattened" {
                $obj = [PSCustomObject]@{ Name = "Item"; Tags = @(@("inner1", "inner2"), "outer") }
                $res = @($obj | Find-ObjectByName "inner1" -Property Tags)
                $res.Count | Should -Be 1
            }

            It "T2-F8-5: Array containing empty strings handled safely" {
                $obj = [PSCustomObject]@{ Name = "Item"; Tags = @("", " ", "actual") }
                $res = @($obj | Find-ObjectByName "actual" -Property Tags -Mode Exact)
                $res.Count | Should -Be 1
            }
        }

        # --- F9 Boundary ---
        Context "F9: Regex Resilience Boundaries" {
            It "T2-F9-1: Empty regex string in -Mode Regex handled cleanly" {
                $items = @([PSCustomObject]@{ Name = "anything" })
                { $res = @($items | Find-ObjectByName "" -Mode Regex) } | Should -Throw
            }

            It "T2-F9-2: Regex special characters in non-regex modes treated literally" {
                $items = @(
                    [PSCustomObject]@{ Name = "regex.*literal[test]" }
                    [PSCustomObject]@{ Name = "regex_other" }
                )
                $res = @($items | Find-ObjectByName ".*literal[test]" -Mode Contains)
                $res.Count | Should -Be 1
                $res[0].Name | Should -Be "regex.*literal[test]"
            }

            It "T2-F9-3: Regex lookahead and lookbehind expressions supported in Regex mode" {
                $items = @(
                    [PSCustomObject]@{ Name = "test123end" }
                    [PSCustomObject]@{ Name = "testABCend" }
                )
                $res = @($items | Find-ObjectByName '(?<=test)\d+(?=end)' -Mode Regex)
                $res.Count | Should -Be 1
                $res[0].Name | Should -Be "test123end"
            }

            It "T2-F9-4: Unicode escape sequences supported in Regex mode" {
                $items = @(
                    [PSCustomObject]@{ Name = "ABC" }
                    [PSCustomObject]@{ Name = "XYZ" }
                )
                $res = @($items | Find-ObjectByName '\u0041\u0042\u0043' -Mode Regex)
                $res.Count | Should -Be 1
                $res[0].Name | Should -Be "ABC"
            }

            It "T2-F9-5: Complex character class ranges evaluated accurately" {
                $items = @(
                    [PSCustomObject]@{ Name = "v1-prod" }
                    [PSCustomObject]@{ Name = "v9-test" }
                    [PSCustomObject]@{ Name = "va-prod" }
                )
                $res = @($items | Find-ObjectByName '^v[0-9]-prod$' -Mode Regex)
                $res.Count | Should -Be 1
                $res[0].Name | Should -Be "v1-prod"
            }
        }

        # --- F10 Boundary ---
        Context "F10: Clean Highlight Boundaries" {
            It "T2-F10-1: -Highlight on object with empty string property does not throw" {
                $obj = [PSCustomObject]@{ Name = "" }
                { $script:res = @($obj | Find-ObjectByName "test" -Highlight) } | Should -Not -Throw
                $script:res.Count | Should -Be 0
            }

            It "T2-F10-2: -Highlight on non-string property converted to string" {
                $obj = [PSCustomObject]@{ Name = "Svc"; Port = 8080 }
                { $script:res = @($obj | Find-ObjectByName "8080" -Property Port -Highlight) } | Should -Not -Throw
                $script:res.Count | Should -Be 1
            }

            It "T2-F10-3: -Highlight with regex meta-characters in Contains mode highlights safely" {
                $obj = [PSCustomObject]@{ Name = "config (v1.0)" }
                { $script:res = @($obj | Find-ObjectByName "(v1.0)" -Highlight) } | Should -Not -Throw
                $script:res.Count | Should -Be 1
            }

            It "T2-F10-4: -Highlight combined with -Count does not corrupt count output" {
                $items = @(
                    [PSCustomObject]@{ Name = "apple" }
                    [PSCustomObject]@{ Name = "apricot" }
                )
                $count = $items | Find-ObjectByName "ap" -Highlight -Count
                $count | Should -Be 2
                $count | Should -BeOfType [int]
            }

            It "T2-F10-5: -Highlight combined with -Quiet does not corrupt boolean output" {
                $items = @([PSCustomObject]@{ Name = "banana" })
                $quiet = $items | Find-ObjectByName "banana" -Highlight -Quiet
                $quiet | Should -Be $true
                $quiet | Should -BeOfType [bool]
            }
        }

        # --- F11 Boundary ---
        Context "F11: Intune Submodule Boundaries" {
            It "T2-F11-1: Idempotent re-import of FindObject.Intune does not throw" {
                if (-not (Test-Path $script:IntunePsm1)) {
                    Test-Path $script:IntunePsm1 | Should -BeTrue
                } else {
                    {
                        Import-Module $script:IntunePsm1 -Force
                        Import-Module $script:IntunePsm1 -Force
                    } | Should -Not -Throw
                }
            }

            It "T2-F11-2: Get-IntuneDevice rejects invalid Top range" {
                if (-not (Test-Path $script:IntunePsm1)) {
                    Test-Path $script:IntunePsm1 | Should -BeTrue
                } else {
                    Import-Module $script:IntunePsm1 -Force
                    { Get-IntuneDevice -Top 0 } | Should -Throw
                }
            }

            It "T2-F11-3: Disconnect-FindObjectGraph runs idempotently when already disconnected" {
                if (-not (Test-Path $script:IntunePsm1)) {
                    Test-Path $script:IntunePsm1 | Should -BeTrue
                } else {
                    Import-Module $script:IntunePsm1 -Force
                    { Disconnect-FindObjectGraph } | Should -Not -Throw
                }
            }

            It "T2-F11-4: Submodule cmdlets do not leak internal helper Invoke-FindObjectGraphRequest" {
                if (-not (Test-Path $script:IntuneManifest)) {
                    Test-Path $script:IntuneManifest | Should -BeTrue
                } else {
                    $manifest = Import-PowerShellDataFile $script:IntuneManifest
                    $manifest.FunctionsToExport | Should -Not -Contain "Invoke-FindObjectGraphRequest"
                }
            }

            It "T2-F11-5: Get-IntuneApp throws auth guard error when disconnected" {
                if (-not (Test-Path $script:IntunePsm1)) {
                    Test-Path $script:IntunePsm1 | Should -BeTrue
                } else {
                    Import-Module $script:IntunePsm1 -Force
                    Disconnect-FindObjectGraph -ErrorAction SilentlyContinue
                    { Get-IntuneApp } | Should -Throw "*Connect-FindObjectGraph*"
                }
            }
        }

        # --- F12 Boundary ---
        Context "F12: Core Module Isolation Boundaries" {
            It "T2-F12-1: Null pipeline input returns null without error" {
                { $script:res = $null | Find-ObjectByName "test" } | Should -Not -Throw
                $script:res | Should -BeNullOrEmpty
            }

            It "T2-F12-2: Set-FindObjectConfig rejects invalid Mode with validation error" {
                { Set-FindObjectConfig -Mode "NonExistentMode" } | Should -Throw
            }

            It "T2-F12-3: Empty SearchTerms string array throws parameter validation error" {
                $obj = [PSCustomObject]@{ Name = "test" }
                { @($obj | Find-ObjectByName -SearchTerms @()) } | Should -Throw
            }

            It "T2-F12-4: Core module does not export internal token or AST parsers" {
                $manifest = Import-PowerShellDataFile $script:CoreManifest
                $manifest.FunctionsToExport | Should -Not -Contain "ConvertTo-FindObjectTokens"
                $manifest.FunctionsToExport | Should -Not -Contain "ConvertTo-FindObjectAst"
            }

            It "T2-F12-5: Core module configuration retains and updates session state" {
                Set-FindObjectConfig -Mode Fuzzy | Out-Null
                (Get-FindObjectConfig).Mode | Should -Be "Fuzzy"
                Set-FindObjectConfig -Mode Contains | Out-Null
                (Get-FindObjectConfig).Mode | Should -Be "Contains"
            }
        }
    }

    # =========================================================================
    # TIER 3: CROSS-FEATURE COMBINATIONS (Pairwise & Multi-Feature Interactions)
    # =========================================================================
    Context "Tier 3: Cross-Feature Combinations" -Tags "Tier3" {

        It "T3-01: Quoted phrases inside parentheses with NOT (F1 + F3 + F4 + F5)" {
            $items = @(
                [PSCustomObject]@{ Name = "Visual Studio Community" }
                [PSCustomObject]@{ Name = "Visual Studio Code Insiders" }
                [PSCustomObject]@{ Name = "Visual Studio Code Stable" }
                [PSCustomObject]@{ Name = "Sublime Text" }
            )
            $res = @($items | Find-ObjectByName '("Visual Studio" OR "VS Code") AND NOT "Insiders"')
            $res.Count | Should -Be 2
            $names = $res | ForEach-Object { $_.Name }
            $names | Should -Contain "Visual Studio Community"
            $names | Should -Contain "Visual Studio Code Stable"
        }

        It "T3-02: Dotted property paths with quoted phrase and boolean AND (F1 + F4 + F6)" {
            $items = @(
                [PSCustomObject]@{ Meta = [PSCustomObject]@{ Category = "Machine Learning Core" } }
                [PSCustomObject]@{ Meta = [PSCustomObject]@{ Category = "Machine Learning Peripheral" } }
                [PSCustomObject]@{ Meta = [PSCustomObject]@{ Category = "Web Core" } }
            )
            $res = @($items | Find-ObjectByName '"Machine Learning" AND Core' -Property "Meta.Category")
            $res.Count | Should -Be 1
            $res[0].Meta.Category | Should -Be "Machine Learning Core"
        }

        It "T3-03: Array property evaluated in Exact mode with boolean AND (F2 + F3 + F8)" {
            $items = @(
                [PSCustomObject]@{ Name = "Srv1"; Roles = @("Domain Controller", "DNS Server") }
                [PSCustomObject]@{ Name = "Srv2"; Roles = @("Domain Controller", "File Server") }
                [PSCustomObject]@{ Name = "Srv3"; Roles = @("DNS Server") }
            )
            $res = @($items | Find-ObjectByName '"Domain Controller" AND "DNS Server"' -Property Roles -Mode Exact)
            $res.Count | Should -Be 1
            $res[0].Name | Should -Be "Srv1"
        }

        It "T3-04: Dotted path navigating into array of objects (F6 + F8)" {
            $items = @(
                [PSCustomObject]@{
                    Team = "Core"
                    Members = @(
                        [PSCustomObject]@{ Role = "Lead Developer" }
                        [PSCustomObject]@{ Role = "QA Specialist" }
                    )
                }
                [PSCustomObject]@{
                    Team = "Ops"
                    Members = @(
                        [PSCustomObject]@{ Role = "Site Reliability Engineer" }
                    )
                }
            )
            $res = @($items | Find-ObjectByName '"Site Reliability Engineer"' -Property "Members.Role" -Mode Exact)
            $res.Count | Should -Be 1
            $res[0].Team | Should -Be "Ops"
        }

        It "T3-05: Array property matching with Regex mode (F8 + F9)" {
            $items = @(
                [PSCustomObject]@{ Name = "ClusterA"; NodeIds = @("node-prod-001", "node-prod-002") }
                [PSCustomObject]@{ Name = "ClusterB"; NodeIds = @("node-dev-001") }
            )
            $res = @($items | Find-ObjectByName '^node-prod-\d{3}$' -Property NodeIds -Mode Regex)
            $res.Count | Should -Be 1
            $res[0].Name | Should -Be "ClusterA"
        }

        It "T3-06: Wildcard property inspection across nested objects and arrays (F6 + F7 + F8)" {
            $items = @(
                [PSCustomObject]@{
                    Id = 501
                    Tags = @("Critical", "Audit")
                    Details = [PSCustomObject]@{ Region = "us-east-1" }
                }
                [PSCustomObject]@{
                    Id = 502
                    Tags = @("Low")
                    Details = [PSCustomObject]@{ Region = "eu-west-1" }
                }
            )
            $res = @($items | Find-ObjectByName "501" -Property *)
            $res.Count | Should -Be 1
            $res[0].Id | Should -Be 501
        }

        It "T3-07: Highlighting combined with quoted phrases and boolean OR (F1 + F10)" {
            $items = @(
                [PSCustomObject]@{ Name = "Windows Server 2022" }
                [PSCustomObject]@{ Name = "Ubuntu Linux 24.04" }
                [PSCustomObject]@{ Name = "Red Hat Enterprise" }
            )
            $res = @($items | Find-ObjectByName '"Windows Server" OR "Ubuntu Linux"' -Highlight)
            $res.Count | Should -Be 2
            $esc = [char]27
            $res[0].Name | Should -Match ([regex]::Escape("${esc}[1;33m"))
            $res[1].Name | Should -Match ([regex]::Escape("${esc}[1;33m"))
        }

        It "T3-08: Unary NOT combined with dotted property path (F5 + F6)" {
            $items = @(
                [PSCustomObject]@{ Account = [PSCustomObject]@{ Status = "Active" }; User = "user1" }
                [PSCustomObject]@{ Account = [PSCustomObject]@{ Status = "Disabled" }; User = "user2" }
            )
            $res = @($items | Find-ObjectByName "NOT Disabled" -Property "Account.Status")
            $res.Count | Should -Be 1
            $res[0].User | Should -Be "user1"
        }

        It "T3-09: Regex mode with unary NOT and parentheses: NOT (^[0-9]+$) (F4 + F5 + F9)" {
            $items = @(
                [PSCustomObject]@{ Code = "12345" }
                [PSCustomObject]@{ Code = "ABCDE" }
                [PSCustomObject]@{ Code = "99999" }
            )
            $res = @($items | Find-ObjectByName "NOT (^[0-9]+$)" -Property Code -Mode Regex)
            $res.Count | Should -Be 1
            $res[0].Code | Should -Be "ABCDE"
        }

        It "T3-10: Wildcard non-string search with Boolean precedence: (100 OR 200) AND NOT 500 (F3 + F4 + F7)" {
            $items = @(
                [PSCustomObject]@{ Name = "A"; Code = 100; Error = 0 }
                [PSCustomObject]@{ Name = "B"; Code = 200; Error = 500 }
                [PSCustomObject]@{ Name = "C"; Code = 300; Error = 0 }
            )
            $res = @($items | Find-ObjectByName "(100 OR 200) AND NOT 500" -Property *)
            $res.Count | Should -Be 1
            $res[0].Name | Should -Be "A"
        }

        It "T3-11: Array property with Prefix mode and parentheses (F4 + F5 + F8)" {
            $items = @(
                [PSCustomObject]@{ Name = "App1"; Environments = @("development", "testing") }
                [PSCustomObject]@{ Name = "App2"; Environments = @("production", "staging") }
                [PSCustomObject]@{ Name = "App3"; Environments = @("development", "production") }
            )
            $res = @($items | Find-ObjectByName "(dev OR test) AND NOT prod" -Property Environments -Mode StartsWith)
            $res.Count | Should -Be 1
            $res[0].Name | Should -Be "App1"
        }

        It "T3-12: Case-sensitive matching with quoted phrases and boolean logic (F1 + F2 + F5)" {
            $items = @(
                [PSCustomObject]@{ Name = "API Gateway Core" }
                [PSCustomObject]@{ Name = "api gateway core" }
                [PSCustomObject]@{ Name = "API Gateway Internal" }
            )
            $res = @($items | Find-ObjectByName '"API Gateway" AND NOT Internal' -CaseSensitive)
            $res.Count | Should -Be 1
            $res[0].Name | Should -Be "API Gateway Core"
        }

        It "T3-13: Result limiting (-First, -Skip) with boolean precedence and dotted properties (F3 + F6)" {
            $items = 1..20 | ForEach-Object {
                [PSCustomObject]@{
                    Meta = [PSCustomObject]@{
                        Env = if ($_ % 2 -eq 0) { "Production" } else { "Development" }
                        Tier = if ($_ -gt 10) { "Gold" } else { "Silver" }
                    }
                    Index = $_
                }
            }
            # Production AND Gold -> Even numbers > 10: 12, 14, 16, 18, 20 (5 items)
            $res = @($items | Find-ObjectByName "Production AND Gold" -Property "Meta.Env" -Skip 2 -First 2)
            # Dotted search across Meta
            $resAll = @($items | Find-ObjectByName "Production" -Property "Meta.Env" -Skip 2 -First 2)
            $resAll.Count | Should -Be 2
            $resAll[0].Index | Should -Be 6
            $resAll[1].Index | Should -Be 8
        }

        It "T3-14: Count and Quiet switches with quoted phrases and array properties (F1 + F8)" {
            $items = @(
                [PSCustomObject]@{ Name = "App1"; Tags = @("Cloud Native", "Kubernetes") }
                [PSCustomObject]@{ Name = "App2"; Tags = @("Legacy Monolith") }
            )
            $count = $items | Find-ObjectByName '"Cloud Native"' -Property Tags -Count
            $count | Should -Be 1

            $quiet = $items | Find-ObjectByName '"Cloud Native"' -Property Tags -Quiet
            $quiet | Should -Be $true
        }

        It "T3-15: Chained pipeline filtering through fob twice (Composition)" {
            $items = @(
                [PSCustomObject]@{ Department = "Security"; Title = "Senior Analyst" }
                [PSCustomObject]@{ Department = "Security"; Title = "Junior Analyst" }
                [PSCustomObject]@{ Department = "Sales"; Title = "Senior Executive" }
            )
            $res = @($items | fob "Security" -Property Department | fob "Senior" -Property Title)
            $res.Count | Should -Be 1
            $res[0].Title | Should -Be "Senior Analyst"
        }

        It "T3-16: Dotted property resolution with -AsString parameter fallback" {
            $strings = @("Server.Production.Primary", "Server.Development.Secondary")
            $res = @($strings | Find-ObjectByName "Production" -AsString)
            $res.Count | Should -Be 1
            $res[0] | Should -Be "Server.Production.Primary"
        }

        It "T3-17: Fuzzy mode with -First 1 early termination" {
            $items = @(
                [PSCustomObject]@{ Name = "FindObject.psm1" }
                [PSCustomObject]@{ Name = "FindObject.psd1" }
                [PSCustomObject]@{ Name = "FindObject.Tests.ps1" }
            )
            $res = @($items | Find-ObjectByName "fndobj" -Mode Fuzzy -First 1)
            $res.Count | Should -Be 1
            $res[0].Name | Should -Be "FindObject.psm1"
        }

        It "T3-18: StartsWith mode with array property and boolean OR" {
            $items = @(
                [PSCustomObject]@{ Name = "Tool1"; Prefixes = @("aws-cli", "az-cli") }
                [PSCustomObject]@{ Name = "Tool2"; Prefixes = @("gcloud", "oci") }
            )
            $res = @($items | Find-ObjectByName "aws OR gcloud" -Property Prefixes -Mode StartsWith)
            $res.Count | Should -Be 2
        }

        It "T3-19: Unary NOT with -Property * on heterogeneous PSCustomObject" {
            $items = @(
                [PSCustomObject]@{ Name = "Node1"; IP = "10.0.0.1"; Status = "Error" }
                [PSCustomObject]@{ Name = "Node2"; IP = "10.0.0.2"; Status = "OK" }
            )
            $res = @($items | Find-ObjectByName "NOT Error" -Property *)
            $res.Count | Should -Be 1
            $res[0].Name | Should -Be "Node2"
        }

        It 'T3-20: Parentheses with nested NOT and quoted phrases: NOT ("legacy app" OR "deprecated api")' {
            $items = @(
                [PSCustomObject]@{ Name = "modern service" }
                [PSCustomObject]@{ Name = "legacy app v1" }
                [PSCustomObject]@{ Name = "deprecated api service" }
            )
            $res = @($items | Find-ObjectByName 'NOT ("legacy app" OR "deprecated api")')
            $res.Count | Should -Be 1
            $res[0].Name | Should -Be "modern service"
        }

        It "T3-21: Multi-level dotted path with integer leaf value" {
            $items = @(
                [PSCustomObject]@{ Cluster = [PSCustomObject]@{ Spec = [PSCustomObject]@{ Replicas = 3 } } }
                [PSCustomObject]@{ Cluster = [PSCustomObject]@{ Spec = [PSCustomObject]@{ Replicas = 10 } } }
            )
            $res = @($items | Find-ObjectByName "10" -Property "Cluster.Spec.Replicas")
            $res.Count | Should -Be 1
            $res[0].Cluster.Spec.Replicas | Should -Be 10
        }

        It "T3-22: Array property containing dates evaluated with StartsWith" {
            $items = @(
                [PSCustomObject]@{ Name = "Batch1"; AuditDates = @("2026-01-01", "2026-02-01") }
                [PSCustomObject]@{ Name = "Batch2"; AuditDates = @("2025-12-01") }
            )
            $res = @($items | Find-ObjectByName "2026" -Property AuditDates -Mode StartsWith)
            $res.Count | Should -Be 1
            $res[0].Name | Should -Be "Batch1"
        }

        It "T3-23: Highlighting multiple quoted phrases across multiple objects" {
            $items = @(
                [PSCustomObject]@{ Description = "Setup Windows Server now" }
                [PSCustomObject]@{ Description = "Install Red Hat now" }
            )
            $res = @($items | Find-ObjectByName '"Windows Server" OR "Red Hat"' -Property Description -Highlight)
            $res.Count | Should -Be 2
        }

        It "T3-24: Chained pipeline resilience: first fob succeeds, second malformed regex halts cleanly" {
            $items = @([PSCustomObject]@{ Name = "valid" })
            { @($items | fob "valid" | fob "[" -Mode Regex) } | Should -Throw
        }

        It "T3-25: Core module configuration overriding Mode while filtering dotted array properties" {
            Set-FindObjectConfig -Mode Exact | Out-Null
            $items = @(
                [PSCustomObject]@{ Config = [PSCustomObject]@{ Tags = @("audit", "prod") } }
                [PSCustomObject]@{ Config = [PSCustomObject]@{ Tags = @("auditing", "dev") } }
            )
            # Default mode is now Exact
            $res = @($items | Find-ObjectByName "audit" -Property "Config.Tags")
            $res.Count | Should -Be 1
        }
    }

    # =========================================================================
    # TIER 4: REAL-WORLD APPLICATION SCENARIOS
    # =========================================================================
    Context "Tier 4: Real-World Application Scenarios" -Tags "Tier4" {

        # Scenario 1: Windows Process Filtering & Triage
        Context "Scenario 1: Windows Process Triage" {
            BeforeAll {
                $script:ProcessData = @(
                    [PSCustomObject]@{ Name = "chrome"; Id = 1042; WorkingSet = 120450000; Path = "C:\Program Files\Google\Chrome\chrome.exe"; CommandLine = "--type=normal" }
                    [PSCustomObject]@{ Name = "chrome"; Id = 1044; WorkingSet = 45200000;  Path = "C:\Program Files\Google\Chrome\chrome.exe"; CommandLine = "--type=renderer --extension" }
                    [PSCustomObject]@{ Name = "chrome"; Id = 1046; WorkingSet = 32100000;  Path = "C:\Program Files\Google\Chrome\chrome.exe"; CommandLine = "--type=crashpad-handler" }
                    [PSCustomObject]@{ Name = "msedge"; Id = 2012; WorkingSet = 110500000; Path = "C:\Program Files (x86)\Microsoft\Edge\msedge.exe"; CommandLine = "--type=normal" }
                    [PSCustomObject]@{ Name = "svchost"; Id = 890; WorkingSet = 15400000;  Path = "C:\Windows\System32\svchost.exe"; CommandLine = "-k DcomLaunch" }
                    [PSCustomObject]@{ Name = "node";   Id = 5540; WorkingSet = 210000000; Path = "C:\Program Files\nodejs\node.exe"; CommandLine = "server.js --inspect=9229" }
                )
            }

            It "T4-01: Filter primary browser processes excluding background crash handlers" {
                $res = @($script:ProcessData | Find-ObjectByName "(chrome OR msedge) AND NOT crashpad" -Property *)
                $res.Count | Should -Be 3
                $ids = $res | ForEach-Object { $_.Id }
                $ids | Should -Not -Contain 1046
            }

            It "T4-02: Locate developer processes with inspect port enabled" {
                $res = @($script:ProcessData | Find-ObjectByName '"node.exe" AND "--inspect"' -Property *)
                $res.Count | Should -Be 1
                $res[0].Name | Should -Be "node"
            }

            It "T4-03: Process paging with -First and -Skip on high-cardinality workloads" {
                $res = @($script:ProcessData | Find-ObjectByName "chrome" -Skip 1 -First 2)
                $res.Count | Should -Be 2
                $res[0].Id | Should -Be 1044
                $res[1].Id | Should -Be 1046
            }

            It "T4-04: Fast existence check with -Quiet for active service host" {
                $exists = $script:ProcessData | Find-ObjectByName "svchost" -Quiet
                $exists | Should -Be $true
            }
        }

        # Scenario 2: Windows Service Audit & Security Hardening
        Context "Scenario 2: Windows Service Audit & Security Hardening" {
            BeforeAll {
                $script:ServiceData = @(
                    [PSCustomObject]@{ Name = "WinDefend"; DisplayName = "Microsoft Defender Antivirus Service"; Status = "Running"; StartType = "Automatic"; PathName = "C:\ProgramData\Microsoft\Windows Defender\Platform\MsMpEng.exe"; ServiceAccount = "LocalSystem" }
                    [PSCustomObject]@{ Name = "MpsSvc"; DisplayName = "Windows Defender Firewall"; Status = "Running"; StartType = "Automatic"; PathName = "C:\Windows\System32\svchost.exe -k LocalServiceNoNetwork"; ServiceAccount = "NT AUTHORITY\LocalService" }
                    [PSCustomObject]@{ Name = "DiagTrack"; DisplayName = "Connected User Experiences and Telemetry"; Status = "Stopped"; StartType = "Disabled"; PathName = "C:\Windows\System32\svchost.exe -k utcsvc"; ServiceAccount = "NT AUTHORITY\LocalService" }
                    [PSCustomObject]@{ Name = "VulnerableApp"; DisplayName = "Legacy Backup Agent"; Status = "Running"; StartType = "Automatic"; PathName = "C:\Program Files\Vulnerable App\agent.exe"; ServiceAccount = "NT AUTHORITY\LocalService" }
                    [PSCustomObject]@{ Name = "UnquotedSvc"; DisplayName = "Custom Monitoring Daemon"; Status = "Running"; StartType = "Automatic"; PathName = "C:\Program Files\Custom Daemon\daemon.exe"; ServiceAccount = "corp\svc_monitor" }
                )
            }

            It "T4-05: Audit active security services (Defender OR Firewall) AND Running" {
                $res = @($script:ServiceData | Find-ObjectByName "(Defender OR Firewall) AND Running" -Property *)
                $res.Count | Should -Be 2
                $names = $res | ForEach-Object { $_.Name }
                $names | Should -Contain "WinDefend"
                $names | Should -Contain "MpsSvc"
            }

            It "T4-06: Locate services running under non-standard custom service accounts" {
                $res = @($script:ServiceData | Find-ObjectByName 'NOT "LocalSystem" AND NOT "NT AUTHORITY"' -Property ServiceAccount)
                $res.Count | Should -Be 1
                $res[0].Name | Should -Be "UnquotedSvc"
            }

            It "T4-07: Detect unquoted service paths containing spaces via Regex mode" {
                # Unquoted path: starts with C:\, contains space before .exe, does not start with quote
                $res = @($script:ServiceData | Find-ObjectByName '^[A-Za-z]:\\[^"]*\s[^"]*\.exe' -Property PathName -Mode Regex)
                $res.Count | Should -Be 3
                $names = $res | ForEach-Object { $_.Name }
                $names | Should -Contain "WinDefend"
                $names | Should -Contain "VulnerableApp"
                $names | Should -Contain "UnquotedSvc"
            }

            It "T4-08: Filter telemetry and diagnostic services with disabled status" {
                $res = @($script:ServiceData | Find-ObjectByName "(Telemetry OR Diag) AND Disabled" -Property *)
                $res.Count | Should -Be 1
                $res[0].Name | Should -Be "DiagTrack"
            }
        }

        # Scenario 3: Active Directory / Entra ID User Auditing
        Context "Scenario 3: Active Directory / Entra ID User Auditing" {
            BeforeAll {
                $script:UserData = @(
                    [PSCustomObject]@{
                        SamAccountName = "jdoe"
                        UserPrincipalName = "jdoe@contoso.com"
                        Department = "IT Infrastructure"
                        Enabled = $true
                        Manager = [PSCustomObject]@{ DisplayName = "Alice Smith"; Email = "asmith@contoso.com" }
                        MemberOf = @("CN=Domain Admins,OU=Groups,DC=contoso,DC=com", "CN=VPN Users,OU=Groups,DC=contoso,DC=com")
                    }
                    [PSCustomObject]@{
                        SamAccountName = "bg_admin"
                        UserPrincipalName = "bg_admin@contoso.com"
                        Department = "Security Operations"
                        Enabled = $true
                        Manager = [PSCustomObject]@{ DisplayName = "Alice Smith"; Email = "asmith@contoso.com" }
                        MemberOf = @("CN=Domain Admins,OU=Groups,DC=contoso,DC=com", "CN=BreakGlass,OU=Groups,DC=contoso,DC=com")
                    }
                    [PSCustomObject]@{
                        SamAccountName = "ext_contractor"
                        UserPrincipalName = "ext_contractor@contractor.contoso.com"
                        Department = "Software Engineering"
                        Enabled = $false
                        Manager = [PSCustomObject]@{ DisplayName = "Bob Jones"; Email = "bjones@contoso.com" }
                        MemberOf = @("CN=Developers,OU=Groups,DC=contoso,DC=com")
                    }
                )
            }

            It "T4-09: Triage Domain Admins excluding emergency BreakGlass accounts" {
                $res = @($script:UserData | Find-ObjectByName '"Domain Admins" AND NOT BreakGlass' -Property MemberOf)
                $res.Count | Should -Be 1
                $res[0].SamAccountName | Should -Be "jdoe"
            }

            It "T4-10: Audit users reporting to specific manager via dotted property" {
                $res = @($script:UserData | Find-ObjectByName '"Alice Smith"' -Property "Manager.DisplayName")
                $res.Count | Should -Be 2
                $names = $res | ForEach-Object { $_.SamAccountName }
                $names | Should -Contain "jdoe"
                $names | Should -Contain "bg_admin"
            }

            It "T4-11: Detect disabled contractor accounts" {
                $res = @($script:UserData | Find-ObjectByName "contractor AND False" -Property *)
                $res.Count | Should -Be 1
                $res[0].SamAccountName | Should -Be "ext_contractor"
            }

            It "T4-12: Total count of active staff in IT or Security departments" {
                $count = $script:UserData | Find-ObjectByName "(Infrastructure OR Security) AND True" -Property * -Count
                $count | Should -Be 2
            }
        }

        # Scenario 4: Intune Device & Compliance Inventory
        Context "Scenario 4: Intune Device & Compliance Inventory" {
            BeforeAll {
                $script:DeviceData = @(
                    [PSCustomObject]@{
                        id = "dev-001"
                        deviceName = "TONY-WIN11-PRO"
                        operatingSystem = "Windows"
                        osVersion = "10.0.22631.3007"
                        complianceState = "Compliant"
                        hardwareInformation = [PSCustomObject]@{ totalStorageSpace = 1000204886016 }
                        configurationProfiles = @("BitLocker Base", "WiFi Enterprise", "Defender EDR")
                    }
                    [PSCustomObject]@{
                        id = "dev-002"
                        deviceName = "TONY-MACBOOK-AIR"
                        operatingSystem = "macOS"
                        osVersion = "14.4.1"
                        complianceState = "NonCompliant"
                        hardwareInformation = [PSCustomObject]@{ totalStorageSpace = 500102443008 }
                        configurationProfiles = @("FileVault Base", "WiFi Enterprise")
                    }
                    [PSCustomObject]@{
                        id = "dev-003"
                        deviceName = "SALES-WIN10-LTP"
                        operatingSystem = "Windows"
                        osVersion = "10.0.19045.4046"
                        complianceState = "NonCompliant"
                        hardwareInformation = [PSCustomObject]@{ totalStorageSpace = 256000000000 }
                        configurationProfiles = @("BitLocker Base")
                    }
                    [PSCustomObject]@{
                        id = "dev-004"
                        deviceName = "EXEC-IPAD-PRO"
                        operatingSystem = "iOS"
                        osVersion = "17.4.1"
                        complianceState = "Compliant"
                        hardwareInformation = [PSCustomObject]@{ totalStorageSpace = 128000000000 }
                        configurationProfiles = @("AirWatch MDM")
                    }
                )
            }

            It "T4-13: Identify Non-Compliant enterprise laptops: (Windows OR macOS) AND NonCompliant" {
                $res = @($script:DeviceData | Find-ObjectByName "(Windows OR macOS) AND NonCompliant" -Property *)
                $res.Count | Should -Be 2
                $names = $res | ForEach-Object { $_.deviceName }
                $names | Should -Contain "TONY-MACBOOK-AIR"
                $names | Should -Contain "SALES-WIN10-LTP"
            }

            It "T4-14: Audit devices with missing Defender EDR profile using array evaluation" {
                $res = @($script:DeviceData | Find-ObjectByName "Windows AND NOT Defender" -Property *)
                $res.Count | Should -Be 1
                $res[0].deviceName | Should -Be "SALES-WIN10-LTP"
            }

            It "T4-15: Query storage capacity via dotted hardware path" {
                $res = @($script:DeviceData | Find-ObjectByName "1000204886016" -Property "hardwareInformation.totalStorageSpace" -Mode Exact)
                $res.Count | Should -Be 1
                $res[0].deviceName | Should -Be "TONY-WIN11-PRO"
            }

            It "T4-16: Fast existence test for iOS mobile devices" {
                $hasIos = $script:DeviceData | Find-ObjectByName "iOS" -Property operatingSystem -Quiet
                $hasIos | Should -Be $true
            }
        }

        # Scenario 5: Web Server Access Log Inspection
        Context "Scenario 5: Web Server Access Log Inspection" {
            BeforeAll {
                $script:LogData = @(
                    [PSCustomObject]@{ ClientIP = "192.168.1.100"; Method = "GET";  UriStem = "/index.html"; StatusCode = 200; UserAgent = "Mozilla/5.0 Chrome/120.0" }
                    [PSCustomObject]@{ ClientIP = "10.0.0.50";     Method = "POST"; UriStem = "/api/v2/checkout"; StatusCode = 500; UserAgent = "ShopMobile/1.2" }
                    [PSCustomObject]@{ ClientIP = "10.0.0.51";     Method = "POST"; UriStem = "/api/v2/checkout"; StatusCode = 503; UserAgent = "ShopMobile/1.2" }
                    [PSCustomObject]@{ ClientIP = "192.168.1.101"; Method = "GET";  UriStem = "/healthz"; StatusCode = 500; UserAgent = "KubeletHealthCheck" }
                    [PSCustomObject]@{ ClientIP = "45.33.32.156";  Method = "GET";  UriStem = "/wp-login.php"; StatusCode = 404; UserAgent = "sqlmap/1.6.12#stable" }
                )
            }

            It "T4-17: Detect critical 5xx server errors excluding health checks" {
                $res = @($script:LogData | Find-ObjectByName "(500 OR 503) AND NOT healthz" -Property *)
                $res.Count | Should -Be 2
                $ips = $res | ForEach-Object { $_.ClientIP }
                $ips | Should -Contain "10.0.0.50"
                $ips | Should -Contain "10.0.0.51"
            }

            It "T4-18: Locate security penetration scanning user agents" {
                $res = @($script:LogData | Find-ObjectByName '"sqlmap" OR "nikto" OR "nmap"' -Property UserAgent)
                $res.Count | Should -Be 1
                $res[0].ClientIP | Should -Be "45.33.32.156"
            }

            It "T4-19: Triage API v2 POST operations" {
                $res = @($script:LogData | Find-ObjectByName '"/api/v2/" AND POST' -Property *)
                $res.Count | Should -Be 2
            }

            It "T4-20: Count requests returning HTTP 200 status code" {
                $count = $script:LogData | Find-ObjectByName "200" -Property StatusCode -Mode Exact -Count
                $count | Should -Be 1
            }
        }

        # Scenario 6: CI/CD Software Bill-of-Materials & Vulnerability Audit
        Context "Scenario 6: CI/CD Software Bill-of-Materials & Vulnerability Audit" {
            BeforeAll {
                $script:SbomData = @(
                    [PSCustomObject]@{
                        Package = "System.Text.Json"
                        Version = "8.0.0"
                        License = "MIT"
                        Vulnerabilities = @("CVE-2024-21907:HIGH")
                    }
                    [PSCustomObject]@{
                        Package = "log4j-core"
                        Version = "2.14.1"
                        License = "Apache-2.0"
                        Vulnerabilities = @("CVE-2021-44228:CRITICAL", "CVE-2021-45046:CRITICAL")
                    }
                    [PSCustomObject]@{
                        Package = "legacy-crypto"
                        Version = "1.0.2"
                        License = "GPL-3.0"
                        Vulnerabilities = @("CVE-2026-1101:CRITICAL:Mitigated")
                    }
                    [PSCustomObject]@{
                        Package = "pester"
                        Version = "5.6.1"
                        License = "Apache-2.0"
                        Vulnerabilities = @()
                    }
                )
            }

            It "T4-21: Audit unmitigated CRITICAL vulnerabilities in dependency tree" {
                $res = @($script:SbomData | Find-ObjectByName "CRITICAL AND NOT Mitigated" -Property Vulnerabilities)
                $res.Count | Should -Be 1
                $res[0].Package | Should -Be "log4j-core"
            }

            It "T4-22: Filter restrictive copyleft licenses: (GPL OR AGPL) AND NOT MIT" {
                $res = @($script:SbomData | Find-ObjectByName "(GPL OR AGPL) AND NOT MIT" -Property License)
                $res.Count | Should -Be 1
                $res[0].Package | Should -Be "legacy-crypto"
            }

            It "T4-23: Detect packages with zero known vulnerabilities" {
                $res = @($script:SbomData | Find-ObjectByName "NOT CVE" -Property Vulnerabilities)
                $res.Count | Should -Be 1
                $res[0].Package | Should -Be "pester"
            }

            It "T4-24: Identify modern 2026 CVE vulnerabilities" {
                $res = @($script:SbomData | Find-ObjectByName '"CVE-2026-"' -Property Vulnerabilities)
                $res.Count | Should -Be 1
                $res[0].Package | Should -Be "legacy-crypto"
            }
        }
    }
}