package kvm import ( "testing" "github.com/stretchr/testify/assert" ) // Test validateFloat64Param function func TestValidateFloat64Param(t *testing.T) { tests := []struct { name string params map[string]interface{} paramName string methodName string min float64 max float64 expected float64 expectError bool }{ { name: "valid parameter", params: map[string]interface{}{"test": 50.0}, paramName: "test", methodName: "testMethod", min: 0, max: 100, expected: 50.0, expectError: false, }, { name: "parameter at minimum boundary", params: map[string]interface{}{"test": 0.0}, paramName: "test", methodName: "testMethod", min: 0, max: 100, expected: 0.0, expectError: false, }, { name: "parameter at maximum boundary", params: map[string]interface{}{"test": 100.0}, paramName: "test", methodName: "testMethod", min: 0, max: 100, expected: 100.0, expectError: false, }, { name: "parameter below minimum", params: map[string]interface{}{"test": -1.0}, paramName: "test", methodName: "testMethod", min: 0, max: 100, expected: 0, expectError: true, }, { name: "parameter above maximum", params: map[string]interface{}{"test": 101.0}, paramName: "test", methodName: "testMethod", min: 0, max: 100, expected: 0, expectError: true, }, { name: "wrong parameter type", params: map[string]interface{}{"test": "not a number"}, paramName: "test", methodName: "testMethod", min: 0, max: 100, expected: 0, expectError: true, }, { name: "missing parameter", params: map[string]interface{}{}, paramName: "test", methodName: "testMethod", min: 0, max: 100, expected: 0, expectError: true, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { result, err := validateFloat64Param(tt.params, tt.paramName, tt.methodName, tt.min, tt.max) if tt.expectError { assert.Error(t, err) } else { assert.NoError(t, err) assert.Equal(t, tt.expected, result) } }) } } // Test validateKeysArray function func TestValidateKeysArray(t *testing.T) { tests := []struct { name string params map[string]interface{} methodName string expected []uint8 expectError bool }{ { name: "valid keys array", params: map[string]interface{}{"keys": []interface{}{65.0, 66.0, 67.0}}, methodName: "testMethod", expected: []uint8{65, 66, 67}, expectError: false, }, { name: "empty keys array", params: map[string]interface{}{"keys": []interface{}{}}, methodName: "testMethod", expected: []uint8{}, expectError: false, }, { name: "maximum keys array", params: map[string]interface{}{"keys": []interface{}{1.0, 2.0, 3.0, 4.0, 5.0, 6.0}}, methodName: "testMethod", expected: []uint8{1, 2, 3, 4, 5, 6}, expectError: false, }, { name: "too many keys", params: map[string]interface{}{"keys": []interface{}{1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0}}, methodName: "testMethod", expected: nil, expectError: true, }, { name: "invalid key type", params: map[string]interface{}{"keys": []interface{}{"not a number"}}, methodName: "testMethod", expected: nil, expectError: true, }, { name: "key value out of range (negative)", params: map[string]interface{}{"keys": []interface{}{-1.0}}, methodName: "testMethod", expected: nil, expectError: true, }, { name: "key value out of range (too high)", params: map[string]interface{}{"keys": []interface{}{256.0}}, methodName: "testMethod", expected: nil, expectError: true, }, { name: "wrong parameter type", params: map[string]interface{}{"keys": "not an array"}, methodName: "testMethod", expected: nil, expectError: true, }, { name: "missing keys parameter", params: map[string]interface{}{}, methodName: "testMethod", expected: nil, expectError: true, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { result, err := validateKeysArray(tt.params, tt.methodName) if tt.expectError { assert.Error(t, err) } else { assert.NoError(t, err) assert.Equal(t, tt.expected, result) } }) } } // Test handleKeyboardReportDirect function func TestHandleKeyboardReportDirect(t *testing.T) { tests := []struct { name string params map[string]interface{} expectError bool }{ { name: "valid keyboard report", params: map[string]interface{}{ "modifier": 2.0, // Shift key "keys": []interface{}{65.0, 66.0}, // A, B keys }, expectError: false, }, { name: "empty keys array", params: map[string]interface{}{ "modifier": 0.0, "keys": []interface{}{}, }, expectError: false, }, { name: "invalid modifier", params: map[string]interface{}{ "modifier": 256.0, // Out of range "keys": []interface{}{65.0}, }, expectError: true, }, { name: "invalid keys", params: map[string]interface{}{ "modifier": 0.0, "keys": []interface{}{1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0}, // Too many keys }, expectError: true, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { _, err := handleKeyboardReportDirect(tt.params) if tt.expectError { assert.Error(t, err) } else { assert.NoError(t, err) } }) } } // Test handleAbsMouseReportDirect function func TestHandleAbsMouseReportDirect(t *testing.T) { tests := []struct { name string params map[string]interface{} expectError bool }{ { name: "valid absolute mouse report", params: map[string]interface{}{ "x": 1000.0, "y": 500.0, "buttons": 1.0, // Left button }, expectError: false, }, { name: "boundary values", params: map[string]interface{}{ "x": 0.0, "y": 32767.0, "buttons": 255.0, }, expectError: false, }, { name: "invalid x coordinate", params: map[string]interface{}{ "x": -1.0, // Out of range "y": 500.0, "buttons": 0.0, }, expectError: true, }, { name: "invalid y coordinate", params: map[string]interface{}{ "x": 1000.0, "y": 32768.0, // Out of range "buttons": 0.0, }, expectError: true, }, { name: "invalid buttons", params: map[string]interface{}{ "x": 1000.0, "y": 500.0, "buttons": 256.0, // Out of range }, expectError: true, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { _, err := handleAbsMouseReportDirect(tt.params) if tt.expectError { assert.Error(t, err) } else { assert.NoError(t, err) } }) } } // Test handleRelMouseReportDirect function func TestHandleRelMouseReportDirect(t *testing.T) { tests := []struct { name string params map[string]interface{} expectError bool }{ { name: "valid relative mouse report", params: map[string]interface{}{ "dx": 10.0, "dy": -5.0, "buttons": 2.0, // Right button }, expectError: false, }, { name: "boundary values", params: map[string]interface{}{ "dx": -127.0, "dy": 127.0, "buttons": 0.0, }, expectError: false, }, { name: "invalid dx", params: map[string]interface{}{ "dx": -128.0, // Out of range "dy": 0.0, "buttons": 0.0, }, expectError: true, }, { name: "invalid dy", params: map[string]interface{}{ "dx": 0.0, "dy": 128.0, // Out of range "buttons": 0.0, }, expectError: true, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { _, err := handleRelMouseReportDirect(tt.params) if tt.expectError { assert.Error(t, err) } else { assert.NoError(t, err) } }) } } // Test handleWheelReportDirect function func TestHandleWheelReportDirect(t *testing.T) { tests := []struct { name string params map[string]interface{} expectError bool }{ { name: "valid wheel report", params: map[string]interface{}{ "wheelY": 3.0, }, expectError: false, }, { name: "boundary values", params: map[string]interface{}{ "wheelY": -127.0, }, expectError: false, }, { name: "invalid wheelY", params: map[string]interface{}{ "wheelY": 128.0, // Out of range }, expectError: true, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { _, err := handleWheelReportDirect(tt.params) if tt.expectError { assert.Error(t, err) } else { assert.NoError(t, err) } }) } } // Test handleInputRPCDirect function func TestHandleInputRPCDirect(t *testing.T) { tests := []struct { name string method string params map[string]interface{} expectError bool }{ { name: "keyboard report", method: "keyboardReport", params: map[string]interface{}{ "modifier": 0.0, "keys": []interface{}{65.0}, }, expectError: false, }, { name: "absolute mouse report", method: "absMouseReport", params: map[string]interface{}{ "x": 1000.0, "y": 500.0, "buttons": 1.0, }, expectError: false, }, { name: "relative mouse report", method: "relMouseReport", params: map[string]interface{}{ "dx": 10.0, "dy": -5.0, "buttons": 2.0, }, expectError: false, }, { name: "wheel report", method: "wheelReport", params: map[string]interface{}{ "wheelY": 3.0, }, expectError: false, }, { name: "unknown method", method: "unknownMethod", params: map[string]interface{}{}, expectError: true, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { _, err := handleInputRPCDirect(tt.method, tt.params) if tt.expectError { assert.Error(t, err) } else { assert.NoError(t, err) } }) } } // Test isInputMethod function func TestIsInputMethod(t *testing.T) { tests := []struct { name string method string expected bool }{ { name: "keyboard report method", method: "keyboardReport", expected: true, }, { name: "absolute mouse report method", method: "absMouseReport", expected: true, }, { name: "relative mouse report method", method: "relMouseReport", expected: true, }, { name: "wheel report method", method: "wheelReport", expected: true, }, { name: "non-input method", method: "someOtherMethod", expected: false, }, { name: "empty method", method: "", expected: false, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { result := isInputMethod(tt.method) assert.Equal(t, tt.expected, result) }) } } // Benchmark tests to verify performance improvements func BenchmarkValidateFloat64Param(b *testing.B) { params := map[string]interface{}{"test": 50.0} b.ResetTimer() for i := 0; i < b.N; i++ { _, _ = validateFloat64Param(params, "test", "benchmarkMethod", 0, 100) } } func BenchmarkValidateKeysArray(b *testing.B) { params := map[string]interface{}{"keys": []interface{}{65.0, 66.0, 67.0}} b.ResetTimer() for i := 0; i < b.N; i++ { _, _ = validateKeysArray(params, "benchmarkMethod") } } func BenchmarkHandleKeyboardReportDirect(b *testing.B) { params := map[string]interface{}{ "modifier": 2.0, "keys": []interface{}{65.0, 66.0}, } b.ResetTimer() for i := 0; i < b.N; i++ { _, _ = handleKeyboardReportDirect(params) } } func BenchmarkHandleInputRPCDirect(b *testing.B) { params := map[string]interface{}{ "modifier": 2.0, "keys": []interface{}{65.0, 66.0}, } b.ResetTimer() for i := 0; i < b.N; i++ { _, _ = handleInputRPCDirect("keyboardReport", params) } }