Tests/WinBatchOrchestrator.Tests.ps1

$ModuleRoot = Split-Path -Parent $PSScriptRoot
$AssetsDir = Join-Path $ModuleRoot "Assets"
$ModulePath = Join-Path $ModuleRoot "WinBatchOrchestrator.psm1"

Describe "WinBatchOrchestrator Module" {
    
  # Import the module effectively for testing
  Import-Module $ModulePath -Force

  Context "Initialize-OrchestratorEnvironment" {
    It "Should create directories and deploy assets" {
      InModuleScope WinBatchOrchestrator {
        # Mocks
        Mock Test-Path { 
          # Write-Host "DEBUG: Test-Path Default (False) - $Path"
          return $false 
        } -ParameterFilter { $Path -like "C:\Ops*" }
              
        Mock Test-Path { 
          # Write-Host "DEBUG: Test-Path Assets (True) - $Path"
          return $true 
        } -ParameterFilter { $Path -like "*WinBatchOrchestrator.psm1*" -or $Path -like "*Assets*" -or $Path -like "*version.txt*" }

        Mock New-Item { 
          # Write-Host "DEBUG: New-Item Called for $Path"
          return $true 
        }
        Mock Copy-Item 
        Mock New-EventLog
        Mock Write-Host
        Mock Get-ChildItem { return @() }
        Mock Get-Content { return "0.0.0" }
        Mock Set-Content
              
        # Mock ACL stuff
        Mock Get-Acl { return (New-Object System.Security.AccessControl.DirectorySecurity) }
        Mock Set-Acl
               
        # Run
        Initialize-OrchestratorEnvironment -ServiceAccount "System"

        # Assert
        Assert-MockCalled New-Item -Times 5 # Bin, Scripts, Logs, Secrets, Dashboard (if Assets exist)
        Assert-MockCalled New-EventLog -Times 0 # Should fail gracefully or be mocked to return false on SourceExists check
      }
    }
  }

  Context "Job Management Commands" {
    It "New-OpsJob should call dispatch script" {
      InModuleScope WinBatchOrchestrator {
        Mock Invoke-OpsScript -Verifiable -ParameterFilter { 
          $ScriptName -eq "New-OpsJob.ps1" -and 
          $Arguments.JobName -eq "TestJob" 
        }
                
        New-OpsJob -JobName "TestJob" -ScriptPath "C:\Test.ps1" -ScheduleTime (Get-Date)
                
        Assert-MockCalled Invoke-OpsScript -Times 1
      }
    }

    It "Get-OpsJob should call dispatch script" {
      InModuleScope WinBatchOrchestrator {
        Mock Invoke-OpsScript -Verifiable -ParameterFilter { $ScriptName -eq "Get-OpsJob.ps1" }
        Get-OpsJob -JobName "TestJob"
        Assert-MockCalled Invoke-OpsScript
      }
    }

    It "Start-OpsJob should call dispatch script" {
      InModuleScope WinBatchOrchestrator {
        Mock Invoke-OpsScript -Verifiable -ParameterFilter { $ScriptName -eq "Start-OpsJob.ps1" }
        Start-OpsJob -JobName "TestJob"
        Assert-MockCalled Invoke-OpsScript
      }
    }


    It "Stop-OpsJob should call dispatch script" {
      InModuleScope WinBatchOrchestrator {
        Mock Invoke-OpsScript -Verifiable -ParameterFilter { $ScriptName -eq "Stop-OpsJob.ps1" }
        Stop-OpsJob -JobName "TestJob"
        Assert-MockCalled Invoke-OpsScript
      }
    }

    It "Remove-OpsJob should call dispatch script" {
      InModuleScope WinBatchOrchestrator {
        Mock Invoke-OpsScript -Verifiable -ParameterFilter { $ScriptName -eq "Remove-OpsJob.ps1" }
        Remove-OpsJob -JobName "TestJob"
        Assert-MockCalled Invoke-OpsScript
      }
    }
  }

  Context "Reporting Commands" {
    It "Get-OpsJobHistory should call dispatch script" {
      InModuleScope WinBatchOrchestrator {
        Mock Invoke-OpsScript -Verifiable -ParameterFilter { $ScriptName -eq "Get-OpsJobHistory.ps1" }
        Get-OpsJobHistory -JobName "TestJob"
        Assert-MockCalled Invoke-OpsScript
      }
    }

    It "Get-OpsJobLog should call dispatch script" {
      InModuleScope WinBatchOrchestrator {
        Mock Invoke-OpsScript -Verifiable -ParameterFilter { $ScriptName -eq "Get-OpsJobLog.ps1" }
        Get-OpsJobLog -JobName "TestJob"
        Assert-MockCalled Invoke-OpsScript
      }
    }
  }

  Context "Credential Management" {
    It "New-OpsCreds should call dispatch script" {
      InModuleScope WinBatchOrchestrator {
        Mock Invoke-OpsScript -Verifiable -ParameterFilter { $ScriptName -eq "New-OpsCreds.ps1" }
        New-OpsCreds -Name "DbCreds"
        Assert-MockCalled Invoke-OpsScript
      }
    }
  }
    
    Context "Internal Logic: Invoke-OpsScript" {
         It "Should execute the script if it exists" {
            InModuleScope WinBatchOrchestrator {
                # Test the actual dispatcher logic
                Mock Test-Path { return $true }
                
                # Verify failure on missing script
                Mock Test-Path { return $false } -ParameterFilter { $Path -like "*Missing.ps1" }
                
                { Invoke-OpsScript -ScriptName "Missing.ps1" } | Should Throw "Script not found"
            }
         }
    }
}