mirror of
https://github.com/j3ssie/osmedeus.git
synced 2026-08-22 15:42:27 +02:00
558 lines
11 KiB
Go
558 lines
11 KiB
Go
package parser
|
|
|
|
import (
|
|
"testing"
|
|
|
|
"github.com/j3ssie/osmedeus/v5/internal/core"
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
// Command Requirement Tests
|
|
|
|
func TestDependencyChecker_CheckCommands(t *testing.T) {
|
|
checker := NewDependencyChecker()
|
|
|
|
// Test with commands that should exist on all systems
|
|
err := checker.CheckCommands([]string{"echo", "cat"}, "")
|
|
assert.NoError(t, err)
|
|
}
|
|
|
|
func TestDependencyChecker_CheckCommands_Missing(t *testing.T) {
|
|
checker := NewDependencyChecker()
|
|
|
|
// Test with a command that definitely doesn't exist
|
|
err := checker.CheckCommands([]string{"echo", "nonexistent-tool-xyz-12345"}, "")
|
|
|
|
require.Error(t, err)
|
|
assert.Contains(t, err.Error(), "missing")
|
|
assert.Contains(t, err.Error(), "nonexistent-tool-xyz-12345")
|
|
}
|
|
|
|
func TestDependencyChecker_CheckCommands_Empty(t *testing.T) {
|
|
checker := NewDependencyChecker()
|
|
|
|
// Test with empty list
|
|
err := checker.CheckCommands([]string{}, "")
|
|
assert.NoError(t, err)
|
|
}
|
|
|
|
func TestDependencyChecker_CheckCommands_AllMissing(t *testing.T) {
|
|
checker := NewDependencyChecker()
|
|
|
|
// Test with multiple missing commands
|
|
err := checker.CheckCommands([]string{
|
|
"nonexistent-cmd-abc",
|
|
"nonexistent-cmd-xyz",
|
|
}, "")
|
|
|
|
require.Error(t, err)
|
|
depErr, ok := err.(*DependencyError)
|
|
require.True(t, ok)
|
|
assert.Len(t, depErr.Missing, 2)
|
|
}
|
|
|
|
// Variable Requirement Tests
|
|
|
|
func TestDependencyChecker_CheckVariables(t *testing.T) {
|
|
checker := NewDependencyChecker()
|
|
|
|
deps := []core.VariableDep{
|
|
{
|
|
Name: "target",
|
|
Type: core.VarTypeString,
|
|
Required: true,
|
|
},
|
|
}
|
|
|
|
ctx := map[string]interface{}{
|
|
"target": "example.com",
|
|
}
|
|
|
|
err := checker.CheckVariables(deps, ctx)
|
|
assert.NoError(t, err)
|
|
}
|
|
|
|
func TestDependencyChecker_CheckVariables_Missing(t *testing.T) {
|
|
checker := NewDependencyChecker()
|
|
|
|
deps := []core.VariableDep{
|
|
{
|
|
Name: "target",
|
|
Type: core.VarTypeString,
|
|
Required: true,
|
|
},
|
|
}
|
|
|
|
// Empty context - target is missing
|
|
ctx := map[string]interface{}{}
|
|
|
|
err := checker.CheckVariables(deps, ctx)
|
|
require.Error(t, err)
|
|
assert.Contains(t, err.Error(), "target")
|
|
assert.Contains(t, err.Error(), "missing")
|
|
}
|
|
|
|
func TestDependencyChecker_CheckVariables_NotRequired(t *testing.T) {
|
|
checker := NewDependencyChecker()
|
|
|
|
deps := []core.VariableDep{
|
|
{
|
|
Name: "optional_param",
|
|
Type: core.VarTypeString,
|
|
Required: false,
|
|
},
|
|
}
|
|
|
|
// Empty context - but param is not required
|
|
ctx := map[string]interface{}{}
|
|
|
|
err := checker.CheckVariables(deps, ctx)
|
|
assert.NoError(t, err)
|
|
}
|
|
|
|
func TestDependencyChecker_CheckVariables_DomainType(t *testing.T) {
|
|
checker := NewDependencyChecker()
|
|
|
|
deps := []core.VariableDep{
|
|
{
|
|
Name: "target",
|
|
Type: core.VarTypeDomain,
|
|
Required: true,
|
|
},
|
|
}
|
|
|
|
// Valid domain
|
|
ctx := map[string]interface{}{
|
|
"target": "example.com",
|
|
}
|
|
|
|
err := checker.CheckVariables(deps, ctx)
|
|
assert.NoError(t, err)
|
|
}
|
|
|
|
func TestDependencyChecker_CheckVariables_InvalidDomain(t *testing.T) {
|
|
checker := NewDependencyChecker()
|
|
|
|
deps := []core.VariableDep{
|
|
{
|
|
Name: "target",
|
|
Type: core.VarTypeDomain,
|
|
Required: true,
|
|
},
|
|
}
|
|
|
|
// Invalid domain format
|
|
ctx := map[string]interface{}{
|
|
"target": "not-a-valid-domain",
|
|
}
|
|
|
|
err := checker.CheckVariables(deps, ctx)
|
|
require.Error(t, err)
|
|
assert.Contains(t, err.Error(), "domain")
|
|
}
|
|
|
|
func TestDependencyChecker_CheckVariables_SubdomainType(t *testing.T) {
|
|
checker := NewDependencyChecker()
|
|
|
|
deps := []core.VariableDep{
|
|
{
|
|
Name: "target",
|
|
Type: core.VarTypeSubdomain,
|
|
Required: true,
|
|
},
|
|
}
|
|
|
|
ctx := map[string]interface{}{
|
|
"target": "a.example.com",
|
|
}
|
|
|
|
err := checker.CheckVariables(deps, ctx)
|
|
assert.NoError(t, err)
|
|
}
|
|
|
|
func TestDependencyChecker_CheckVariables_InvalidSubdomain(t *testing.T) {
|
|
checker := NewDependencyChecker()
|
|
|
|
deps := []core.VariableDep{
|
|
{
|
|
Name: "target",
|
|
Type: core.VarTypeSubdomain,
|
|
Required: true,
|
|
},
|
|
}
|
|
|
|
ctx := map[string]interface{}{
|
|
"target": "example.com",
|
|
}
|
|
|
|
err := checker.CheckVariables(deps, ctx)
|
|
require.Error(t, err)
|
|
assert.Contains(t, err.Error(), "subdomain")
|
|
}
|
|
|
|
func TestDependencyChecker_CheckVariables_URLType(t *testing.T) {
|
|
checker := NewDependencyChecker()
|
|
|
|
deps := []core.VariableDep{
|
|
{
|
|
Name: "target",
|
|
Type: core.VarTypeURL,
|
|
Required: true,
|
|
},
|
|
}
|
|
|
|
ctx := map[string]interface{}{
|
|
"target": "https://example.com/path",
|
|
}
|
|
|
|
err := checker.CheckVariables(deps, ctx)
|
|
assert.NoError(t, err)
|
|
}
|
|
|
|
func TestDependencyChecker_CheckVariables_InvalidURL(t *testing.T) {
|
|
checker := NewDependencyChecker()
|
|
|
|
deps := []core.VariableDep{
|
|
{
|
|
Name: "target",
|
|
Type: core.VarTypeURL,
|
|
Required: true,
|
|
},
|
|
}
|
|
|
|
ctx := map[string]interface{}{
|
|
"target": "example.com",
|
|
}
|
|
|
|
err := checker.CheckVariables(deps, ctx)
|
|
require.Error(t, err)
|
|
assert.Contains(t, err.Error(), "url")
|
|
}
|
|
|
|
func TestDependencyChecker_CheckVariables_CIDRType(t *testing.T) {
|
|
checker := NewDependencyChecker()
|
|
|
|
deps := []core.VariableDep{
|
|
{
|
|
Name: "target",
|
|
Type: core.VarTypeCIDR,
|
|
Required: true,
|
|
},
|
|
}
|
|
|
|
ctx := map[string]interface{}{
|
|
"target": "10.0.0.0/8",
|
|
}
|
|
|
|
err := checker.CheckVariables(deps, ctx)
|
|
assert.NoError(t, err)
|
|
}
|
|
|
|
func TestDependencyChecker_CheckVariables_InvalidCIDR(t *testing.T) {
|
|
checker := NewDependencyChecker()
|
|
|
|
deps := []core.VariableDep{
|
|
{
|
|
Name: "target",
|
|
Type: core.VarTypeCIDR,
|
|
Required: true,
|
|
},
|
|
}
|
|
|
|
ctx := map[string]interface{}{
|
|
"target": "10.0.0.0",
|
|
}
|
|
|
|
err := checker.CheckVariables(deps, ctx)
|
|
require.Error(t, err)
|
|
assert.Contains(t, err.Error(), "cidr")
|
|
}
|
|
|
|
func TestDependencyChecker_CheckVariables_RepoType(t *testing.T) {
|
|
checker := NewDependencyChecker()
|
|
|
|
deps := []core.VariableDep{
|
|
{
|
|
Name: "repo",
|
|
Type: core.VarTypeRepo,
|
|
Required: true,
|
|
},
|
|
}
|
|
|
|
ctx := map[string]interface{}{
|
|
"repo": "owner/project",
|
|
}
|
|
|
|
err := checker.CheckVariables(deps, ctx)
|
|
assert.NoError(t, err)
|
|
}
|
|
|
|
func TestDependencyChecker_CheckVariables_RepoType_GitURLs(t *testing.T) {
|
|
checker := NewDependencyChecker()
|
|
|
|
deps := []core.VariableDep{
|
|
{
|
|
Name: "repo",
|
|
Type: core.VarTypeRepo,
|
|
Required: true,
|
|
},
|
|
}
|
|
|
|
tests := []string{
|
|
"https://github.com/osmedeus/assets",
|
|
"https://github.com/osmedeus/assets.git",
|
|
"git@github.com:osmedeus/assets.git",
|
|
"github.com/osmedeus/assets",
|
|
"git://github.com/osmedeus/assets.git",
|
|
}
|
|
|
|
for _, tc := range tests {
|
|
t.Run(tc, func(t *testing.T) {
|
|
ctx := map[string]interface{}{
|
|
"repo": tc,
|
|
}
|
|
err := checker.CheckVariables(deps, ctx)
|
|
assert.NoError(t, err)
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestDependencyChecker_CheckVariables_NumberType(t *testing.T) {
|
|
checker := NewDependencyChecker()
|
|
|
|
deps := []core.VariableDep{
|
|
{
|
|
Name: "threads",
|
|
Type: core.VarTypeNumber,
|
|
Required: true,
|
|
},
|
|
}
|
|
|
|
// Valid number
|
|
ctx := map[string]interface{}{
|
|
"threads": "10",
|
|
}
|
|
|
|
err := checker.CheckVariables(deps, ctx)
|
|
assert.NoError(t, err)
|
|
}
|
|
|
|
func TestDependencyChecker_CheckVariables_InvalidNumber(t *testing.T) {
|
|
checker := NewDependencyChecker()
|
|
|
|
deps := []core.VariableDep{
|
|
{
|
|
Name: "threads",
|
|
Type: core.VarTypeNumber,
|
|
Required: true,
|
|
},
|
|
}
|
|
|
|
// Invalid number format
|
|
ctx := map[string]interface{}{
|
|
"threads": "not-a-number",
|
|
}
|
|
|
|
err := checker.CheckVariables(deps, ctx)
|
|
require.Error(t, err)
|
|
assert.Contains(t, err.Error(), "number")
|
|
}
|
|
|
|
func TestDependencyChecker_CheckVariables_PathType(t *testing.T) {
|
|
checker := NewDependencyChecker()
|
|
|
|
deps := []core.VariableDep{
|
|
{
|
|
Name: "output_dir",
|
|
Type: core.VarTypePath,
|
|
Required: true,
|
|
},
|
|
}
|
|
|
|
// Valid path
|
|
ctx := map[string]interface{}{
|
|
"output_dir": "/tmp/output",
|
|
}
|
|
|
|
err := checker.CheckVariables(deps, ctx)
|
|
assert.NoError(t, err)
|
|
}
|
|
|
|
func TestDependencyChecker_CheckVariables_EmptyPath(t *testing.T) {
|
|
checker := NewDependencyChecker()
|
|
|
|
deps := []core.VariableDep{
|
|
{
|
|
Name: "output_dir",
|
|
Type: core.VarTypePath,
|
|
Required: true,
|
|
},
|
|
}
|
|
|
|
// Empty path
|
|
ctx := map[string]interface{}{
|
|
"output_dir": "",
|
|
}
|
|
|
|
err := checker.CheckVariables(deps, ctx)
|
|
require.Error(t, err)
|
|
}
|
|
|
|
// CheckAll Tests
|
|
|
|
func TestDependencyChecker_CheckAll(t *testing.T) {
|
|
checker := NewDependencyChecker()
|
|
|
|
deps := &core.Dependencies{
|
|
Commands: []string{"echo", "cat"},
|
|
Variables: []core.VariableDep{
|
|
{
|
|
Name: "target",
|
|
Type: core.VarTypeString,
|
|
Required: true,
|
|
},
|
|
},
|
|
}
|
|
|
|
ctx := map[string]interface{}{
|
|
"target": "test-value",
|
|
}
|
|
|
|
err := checker.CheckAll(deps, ctx, "")
|
|
assert.NoError(t, err)
|
|
}
|
|
|
|
func TestDependencyChecker_CheckAll_NilDeps(t *testing.T) {
|
|
checker := NewDependencyChecker()
|
|
|
|
// Should not error with nil dependencies
|
|
err := checker.CheckAll(nil, map[string]interface{}{}, "")
|
|
assert.NoError(t, err)
|
|
}
|
|
|
|
func TestDependencyChecker_CheckAll_CommandsFail(t *testing.T) {
|
|
checker := NewDependencyChecker()
|
|
|
|
deps := &core.Dependencies{
|
|
Commands: []string{"nonexistent-tool-abc-123"},
|
|
}
|
|
|
|
err := checker.CheckAll(deps, map[string]interface{}{}, "")
|
|
require.Error(t, err)
|
|
assert.Contains(t, err.Error(), "nonexistent-tool-abc-123")
|
|
}
|
|
|
|
func TestDependencyChecker_CheckAll_VariablesFail(t *testing.T) {
|
|
checker := NewDependencyChecker()
|
|
|
|
deps := &core.Dependencies{
|
|
Commands: []string{"echo"},
|
|
Variables: []core.VariableDep{
|
|
{
|
|
Name: "required_var",
|
|
Type: core.VarTypeString,
|
|
Required: true,
|
|
},
|
|
},
|
|
}
|
|
|
|
// Missing required variable
|
|
err := checker.CheckAll(deps, map[string]interface{}{}, "")
|
|
require.Error(t, err)
|
|
assert.Contains(t, err.Error(), "required_var")
|
|
}
|
|
|
|
// DependencyError Tests
|
|
|
|
func TestDependencyError_Error_Missing(t *testing.T) {
|
|
err := &DependencyError{
|
|
Type: "commands",
|
|
Missing: []string{"cmd1", "cmd2"},
|
|
}
|
|
|
|
assert.Contains(t, err.Error(), "missing")
|
|
assert.Contains(t, err.Error(), "commands")
|
|
assert.Contains(t, err.Error(), "cmd1")
|
|
assert.Contains(t, err.Error(), "cmd2")
|
|
}
|
|
|
|
func TestDependencyError_Error_Validation(t *testing.T) {
|
|
err := &DependencyError{
|
|
Type: "variables",
|
|
Errors: []string{"var1 is invalid", "var2 is missing"},
|
|
}
|
|
|
|
assert.Contains(t, err.Error(), "validation errors")
|
|
assert.Contains(t, err.Error(), "var1 is invalid")
|
|
}
|
|
|
|
// Helper Function Tests
|
|
|
|
func TestIsValidDomain(t *testing.T) {
|
|
tests := []struct {
|
|
domain string
|
|
expected bool
|
|
}{
|
|
{"example.com", true},
|
|
{"sub.example.com", true},
|
|
{"a.b.c.example.com", true},
|
|
{"example.co.uk", true},
|
|
{"123.example.com", true},
|
|
{"", false},
|
|
{"invalid", false},
|
|
{"-invalid.com", false},
|
|
{"invalid-.com", false},
|
|
{"example", false},
|
|
}
|
|
|
|
for _, tc := range tests {
|
|
t.Run(tc.domain, func(t *testing.T) {
|
|
result, err := core.MatchesVariableType(tc.domain, core.VarTypeDomain)
|
|
require.NoError(t, err)
|
|
assert.Equal(t, tc.expected, result, "domain: %s", tc.domain)
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestIsNumeric(t *testing.T) {
|
|
tests := []struct {
|
|
value string
|
|
expected bool
|
|
}{
|
|
{"123", true},
|
|
{"-123", true},
|
|
{"12.34", true},
|
|
{"-12.34", true},
|
|
{"0", true},
|
|
{"", false},
|
|
{"abc", false},
|
|
{"12abc", false},
|
|
{"12.34.56", false},
|
|
}
|
|
|
|
for _, tc := range tests {
|
|
t.Run(tc.value, func(t *testing.T) {
|
|
result, err := core.MatchesVariableType(tc.value, core.VarTypeNumber)
|
|
require.NoError(t, err)
|
|
assert.Equal(t, tc.expected, result, "value: %s", tc.value)
|
|
})
|
|
}
|
|
}
|
|
|
|
// Global Function Tests
|
|
|
|
func TestCheckDependencies(t *testing.T) {
|
|
deps := &core.Dependencies{
|
|
Commands: []string{"echo"},
|
|
}
|
|
|
|
err := CheckDependencies(deps, map[string]interface{}{}, "")
|
|
assert.NoError(t, err)
|
|
}
|
|
|
|
func TestCheckDependencies_Nil(t *testing.T) {
|
|
err := CheckDependencies(nil, map[string]interface{}{}, "")
|
|
assert.NoError(t, err)
|
|
}
|