tests/Configuration.NRQLCondition.Tests.ps1

. '.\tests\testCases\NRQLConditions.ps1'

Describe 'Set-NRQLConditionConfiguration' {
  $TestCases = Get-NRQLConditionTestCases
  BeforeAll {
    Import-Module '.\NewRelicPS.Configuration.NRQLCondition.psm1' -Force
    Import-Module '.\NewRelicPS.NRQLConditions.psm1' -Force

    $apiKey = 'Fake-Test-Key'
    $fakeKey = 'Fake-Key'
    $accountId = '1234'
    Mock Get-NRQLCondition -ModuleName 'NewRelicPS.Configuration.NRQLCondition' {
      @(
        @{
          expiration = @{
            closeViolationsOnExpiration = $true
            expirationDuration = 360
            openViolationOnExpiration = $true
          }
          id = 67891
          name = 'TestCondition1'
          policyId = 123451
          terms = @{
            operator = 'ABOVE'
            priority = 'CRITICAL'
            threshold = 110
            thresholdDuration = 60
            thresholdOccurrences = 'ALL'
          }
          nrql = @{
            evaluationOffset=3
            query = 'SELECT count(*) FROM AwsLambdaInvocation'
          }
          type = 'STATIC'
          valueFunction = 'SINGLE_VALUE'
          violationTimeLimit = 'TWENTY_FOUR_HOURS'
        }
      )
    }
    Mock Get-NRAlertPolicy -ModuleName 'NewRelicPS.Configuration.NRQLCondition' {
      @(
        @{
          id = '123451'
          incident_preference = 'PER_CONDITION_AND_TARGET'
          name = 'Test1'
        }
      )
    }
    Mock New-NRQLCondition -ModuleName 'NewRelicPS.Configuration.NRQLCondition' {}
    Mock Update-NRQLCondition -ModuleName 'NewRelicPS.Configuration.NRQLCondition' {}
    Mock Remove-NRCondition -ModuleName 'NewRelicPS.Configuration.NRQLCondition' {}
  }
  It 'Creates a defined condition when one does not exist' {

    # Mock compare-object so that the cmdlet doesn't attempt to validate creation of resource
    Mock Compare-Object -ModuleName 'NewRelicPS.Configuration.NRQLCondition' {}

    $definedPolicies = @(
      @{
        Name = 'Test1'
        Conditions = @(
          @{
            type = 'static'
            name = 'TestCondition3'
            terms = @{
              priority = 'CRITICAL'
              threshold = 110
              duration = 60
            }
            nrql = @{
              query = 'SELECT count(*) FROM AwsLambdaInvocation'
            }
          }
        )
      }
    )

    Set-NRQLConditionConfiguration -AdminAPIKey $apiKey -PersonalAPIKey $apiKey -AccountId $accountId -DefinedPolicies $definedPolicies -WarningAction 'SilentlyContinue'
    Assert-MockCalled Update-NRQLCondition -ModuleName 'NewRelicPS.Configuration.NRQLCondition' -Exactly 0
    Assert-MockCalled New-NRQLCondition -ModuleName 'NewRelicPS.Configuration.NRQLCondition' -Exactly 1 -ParameterFilter {
      $PolicyId -eq '123451'
    }
  }

  It 'Does nothing when defined conditions exactly match existing conditions on all policies' {

    # Set the defined policy to match what is mocked
    $definedPolicies = @(
      @{
        Name = 'Test1'
        Conditions = @(
          @{
            type = 'static'
            name = 'TestCondition1'
            terms = @{
              priority = 'CRITICAL'
              threshold = 110
              thresholdDuration = 60
            }
            nrql = @{
              query = 'SELECT count(*) FROM AwsLambdaInvocation'
            }
          }
        )
      }
    )

    Set-NRQLConditionConfiguration -AdminAPIKey $apiKey -PersonalAPIKey $apiKey -AccountId $accountId -DefinedPolicies $definedPolicies
    Assert-MockCalled New-NRQLCondition -ModuleName 'NewRelicPS.Configuration.NRQLCondition' -Exactly 0
    Assert-MockCalled Update-NRQLCondition -ModuleName 'NewRelicPS.Configuration.NRQLCondition' -Exactly 0
    Assert-MockCalled Remove-NRCondition -ModuleName 'NewRelicPS.Configuration.NRQLCondition' -Exactly 0

  }

  It 'Updates an existing condition when defined property <propertyName> does not match' -TestCases $TestCases {
    Set-NRQLConditionConfiguration -AdminAPIKey $apiKey -PersonalAPIKey $apiKey -AccountId $accountId -DefinedPolicies $definedPolicies -WarningAction 'SilentlyContinue'
    Assert-MockCalled Update-NRQLCondition -ModuleName 'NewRelicPS.Configuration.NRQLCondition' -Exactly 1 -ParameterFilter {
      $ConditionId -eq '67891' -and (Get-Variable -Name $propertyName).value -eq $expectedValue
    }
  }

  It 'Removes existing conditions when they are not defined' {

    # This defined policy doesn't have any conditions but the Get-NRQLCondition mock will return one which should be removed
    $definedPolicies = @(
      @{
        Name = 'Test1'
        Conditions = @()
      }
    )

    Set-NRQLConditionConfiguration -AdminAPIKey $apiKey -PersonalAPIKey $apiKey -AccountId $accountId -DefinedPolicies $definedPolicies -WarningAction 'SilentlyContinue'
    Assert-MockCalled New-NRQLCondition -ModuleName 'NewRelicPS.Configuration.NRQLCondition' -Exactly 0
    Assert-MockCalled Update-NRQLCondition -ModuleName 'NewRelicPS.Configuration.NRQLCondition' -Exactly 0
    Assert-MockCalled Remove-NRCondition -ModuleName 'NewRelicPS.Configuration.NRQLCondition' -Exactly 1 -ParameterFilter {
      $ConditionId -eq '67891'
    }
  }
}