Files
osmedeus/test/e2e/decision_inline_test.go
T
j3ssie fba43ba3b5 feat: add string utility functions and decision condition tests
- Add cut_to_file() and cut_space() utility functions for file processing and field extraction
- Add comprehensive E2E tests for decision condition routing with function/command execution
- Add test workflows for decision conditions and inline decision execution
- Add short-mode skip guards to all cloud E2E tests to allow quick test runs
- Register new functions in constants and goja runtime
2026-02-17 17:00:43 +07:00

216 lines
8.1 KiB
Go

package e2e
import (
"strings"
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
// TestDecisionInline_QuickMode tests inline execution in decision cases with default "quick" mode
func TestDecisionInline_QuickMode(t *testing.T) {
log := NewTestLogger(t)
log.Step("Testing decision inline execution with quick mode (default)")
workflowPath := getTestdataPath(t)
stdout, _, err := runCLIWithLog(t, log, "run", "-m", "test-decision-inline", "-t", "example.com", "-F", workflowPath)
require.NoError(t, err)
// Verify workflow completed
log.Info("Asserting workflow completed")
assert.Contains(t, stdout, "completed")
// Verify inline function executed for "quick" case (log_info output is visible)
log.Info("Asserting inline function ran for quick mode")
assert.Contains(t, stdout, "[INLINE] Quick scan selected")
// Verify inline functions (plural) executed
log.Info("Asserting inline functions (plural) ran")
assert.Contains(t, stdout, "[MULTI-FUNC-1] Configuring quick scan")
assert.Contains(t, stdout, "[MULTI-FUNC-2] Quick scan configured")
// Verify inline bash steps appear in step table
log.Info("Asserting inline bash steps appear in results")
assert.Contains(t, stdout, "decision-inline-bash")
assert.Contains(t, stdout, "decision-inline-function")
// Verify inline function+goto worked (inline runs, then jumps)
log.Info("Asserting inline function with goto ran")
assert.Contains(t, stdout, "[INLINE-GOTO] Quick inline before jump")
// Verify goto skipped the skipped-step
log.Info("Asserting skipped step was not executed")
assert.NotContains(t, stdout, "[SKIPPED]")
// Verify final step ran
log.Info("Asserting final step executed")
assert.Contains(t, stdout, "[FINAL] Scan complete for example.com in quick mode")
log.Success("decision inline execution works correctly for quick mode")
}
// TestDecisionInline_DeepMode tests inline execution when a different case is matched
func TestDecisionInline_DeepMode(t *testing.T) {
log := NewTestLogger(t)
log.Step("Testing decision inline execution with deep mode")
workflowPath := getTestdataPath(t)
stdout, _, err := runCLIWithLog(t, log, "run", "-m", "test-decision-inline", "-t", "target.io",
"-p", "scan_mode=deep", "-F", workflowPath)
require.NoError(t, err)
log.Info("Asserting workflow completed")
assert.Contains(t, stdout, "completed")
// Verify deep mode inline function executed
log.Info("Asserting deep mode inline function ran")
assert.Contains(t, stdout, "[INLINE] Deep scan selected")
// Verify deep mode multi-functions executed
log.Info("Asserting deep mode multi-functions ran")
assert.Contains(t, stdout, "[MULTI-FUNC-1] Configuring deep scan")
assert.Contains(t, stdout, "[MULTI-FUNC-2] Deep scan configured")
// Verify quick mode was not executed
log.Info("Asserting quick mode functions did not run")
assert.NotContains(t, stdout, "Quick scan selected")
assert.NotContains(t, stdout, "Configuring quick scan")
// Verify final step
log.Info("Asserting final step executed")
assert.Contains(t, stdout, "[FINAL] Scan complete for target.io in deep mode")
log.Success("decision inline execution works correctly for deep mode")
}
// TestDecisionInline_DefaultCase tests that the default case inline runs when no case matches
func TestDecisionInline_DefaultCase(t *testing.T) {
log := NewTestLogger(t)
log.Step("Testing decision inline with unmatched value (default case)")
workflowPath := getTestdataPath(t)
stdout, _, err := runCLIWithLog(t, log, "run", "-m", "test-decision-inline", "-t", "example.com",
"-p", "scan_mode=unknown", "-F", workflowPath)
require.NoError(t, err)
log.Info("Asserting workflow completed")
assert.Contains(t, stdout, "completed")
// Verify default case inline function executed
log.Info("Asserting default inline function ran")
assert.Contains(t, stdout, "[INLINE] Default mode selected")
// Verify no quick or deep functions ran
log.Info("Asserting non-matching cases did not run")
assert.NotContains(t, stdout, "Quick scan selected")
assert.NotContains(t, stdout, "Deep scan selected")
// Verify default goto worked in branch-and-jump step
log.Info("Asserting default goto jumped correctly")
assert.Contains(t, stdout, "[INLINE-GOTO] Default inline before jump")
assert.NotContains(t, stdout, "[SKIPPED]")
log.Success("default case inline execution works correctly")
}
// TestDecisionInline_GotoSkipsStep tests that goto after inline execution correctly skips intermediate steps
func TestDecisionInline_GotoSkipsStep(t *testing.T) {
log := NewTestLogger(t)
log.Step("Testing that inline+goto correctly skips intermediate steps")
workflowPath := getTestdataPath(t)
stdout, _, err := runCLIWithLog(t, log, "run", "-m", "test-decision-inline", "-t", "example.com", "-F", workflowPath)
require.NoError(t, err)
// The inline function should run before goto
log.Info("Asserting inline function ran before goto")
assert.Contains(t, stdout, "[INLINE-GOTO] Quick inline before jump")
// The skipped-step should not appear
log.Info("Asserting skipped-step was skipped by goto")
assert.NotContains(t, stdout, "[SKIPPED] This should not appear")
// The final-step should appear after the inline goto
log.Info("Asserting final-step ran after goto")
assert.Contains(t, stdout, "[FINAL] Scan complete")
// Verify ordering: inline-goto appears before final
idxInline := strings.Index(stdout, "[INLINE-GOTO]")
idxFinal := strings.Index(stdout, "[FINAL]")
assert.True(t, idxInline >= 0, "inline-goto output not found")
assert.True(t, idxFinal >= 0, "final output not found")
assert.True(t, idxInline < idxFinal, "inline-goto should appear before final step")
log.Success("inline+goto correctly skips intermediate steps")
}
// TestDecisionInline_StepTable tests that inline steps appear correctly in the step results table
func TestDecisionInline_StepTable(t *testing.T) {
log := NewTestLogger(t)
log.Step("Testing inline step entries in step results table")
workflowPath := getTestdataPath(t)
stdout, _, err := runCLIWithLog(t, log, "run", "-m", "test-decision-inline", "-t", "example.com", "-F", workflowPath)
require.NoError(t, err)
// Verify step table contains inline step entries
log.Info("Asserting step table contains inline bash steps")
assert.Contains(t, stdout, "decision-inline-bash")
log.Info("Asserting step table contains inline function steps")
assert.Contains(t, stdout, "decision-inline-function")
// Verify the main workflow steps are present
log.Info("Asserting main steps are present")
assert.Contains(t, stdout, "detect-mode")
assert.Contains(t, stdout, "setup-scan")
assert.Contains(t, stdout, "branch-and-jump")
assert.Contains(t, stdout, "final-step")
// Verify total completed steps > workflow step count (inline steps add extra)
log.Info("Asserting completed steps include inline steps")
assert.Contains(t, stdout, "completed_steps")
log.Success("inline steps appear correctly in step results table")
}
// TestDecisionInline_DryRun tests that the workflow validates in dry-run mode
func TestDecisionInline_DryRun(t *testing.T) {
log := NewTestLogger(t)
log.Step("Testing decision-inline workflow in dry-run mode")
workflowPath := getTestdataPath(t)
stdout, _, err := runCLIWithLog(t, log, "run", "-m", "test-decision-inline", "-t", "example.com", "--dry-run", "-F", workflowPath)
require.NoError(t, err)
log.Info("Asserting dry-run mode")
assert.Contains(t, stdout, "DRY-RUN")
assert.Contains(t, stdout, "test-decision-inline")
log.Success("decision-inline workflow dry-run works correctly")
}
// TestDecisionInline_WorkflowValidate tests that the workflow passes validation
func TestDecisionInline_WorkflowValidate(t *testing.T) {
log := NewTestLogger(t)
log.Step("Testing decision-inline workflow validation")
workflowPath := getTestdataPath(t)
stdout, _, err := runCLIWithLog(t, log, "workflow", "validate", "test-decision-inline", "-F", workflowPath)
require.NoError(t, err)
log.Info("Asserting workflow is valid")
assert.True(t, strings.Contains(stdout, "is valid") || strings.Contains(stdout, "passed all lint checks"),
"expected validation success message")
log.Success("decision-inline workflow passes validation")
}