diff --git a/server/lua-plugins.d/actions/haveibeenpwnd.lua b/server/lua-plugins.d/actions/haveibeenpwnd.lua index 8817f918..52d2f300 100644 --- a/server/lua-plugins.d/actions/haveibeenpwnd.lua +++ b/server/lua-plugins.d/actions/haveibeenpwnd.lua @@ -134,7 +134,7 @@ function nauthilus_call_action(request) end ]] - local script_result, err_run_script = nauthilus_redis.redis_run_script(script, { redis_key }) + local script_result, err_run_script = nauthilus_redis.redis_run_script(script, { redis_key }, {}) nauthilus_util.if_error_raise(err_run_script) if script_result[1] == "send_mail" then diff --git a/server/lualib/redislib/scripts.go b/server/lualib/redislib/scripts.go index 74fa0c62..c124f5ee 100644 --- a/server/lualib/redislib/scripts.go +++ b/server/lualib/redislib/scripts.go @@ -8,11 +8,7 @@ import ( // executeRedisScript executes a given Lua script on the Redis server with specified keys and arguments. func executeRedisScript(script string, keys []string, args ...any) (any, error) { - evalArgs := make([]any, len(keys)+len(args)) - - for i, key := range keys { - evalArgs[i] = key - } + evalArgs := make([]any, len(args)) for i, arg := range args { evalArgs[len(keys)+i] = arg @@ -35,8 +31,8 @@ func RedisRunScript(L *lua.LState) int { ) script := L.CheckString(1) - keys := L.ToTable(2) - args := L.ToTable(3) + keys := L.CheckTable(2) + args := L.CheckTable(3) keys.ForEach(func(k, v lua.LValue) { keyList = append(keyList, v.String()) diff --git a/server/lualib/redislib/scripts_test.go b/server/lualib/redislib/scripts_test.go new file mode 100644 index 00000000..b17e9667 --- /dev/null +++ b/server/lualib/redislib/scripts_test.go @@ -0,0 +1,98 @@ +package redislib + +import ( + "errors" + "testing" + + "github.com/croessner/nauthilus/server/rediscli" + "github.com/go-redis/redismock/v9" + "github.com/stretchr/testify/assert" + lua "github.com/yuin/gopher-lua" +) + +func TestRedisRunScript(t *testing.T) { + testCases := []struct { + name string + script string + keys []string + args []any + expectErr bool + expectRes string + prepareMockRedis func(mock redismock.ClientMock) + }{ + { + name: "ValidScript", + script: "return redis.call('set',KEYS[1],'bar')", + keys: []string{"foo"}, + args: []any{}, + expectErr: false, + expectRes: "mock result", + prepareMockRedis: func(mock redismock.ClientMock) { + mock.ExpectEval("return redis.call('set',KEYS[1],'bar')", []string{"foo"}).SetVal("mock result") + }, + }, + { + name: "InvalidScript", + script: "return redis.call('set',KEYS[1])", // missing value for 'set' + keys: []string{"foo"}, + args: []any{}, + expectErr: true, + expectRes: "", + prepareMockRedis: func(mock redismock.ClientMock) { + mock.ExpectEval("return redis.call('set',KEYS[1])", []string{"foo"}).SetErr(errors.New("missing value for 'set'")) + }, + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + db, mock := redismock.NewClientMock() + if db == nil || mock == nil { + t.Fatalf("Failed to create Redis mock client.") + } + + tc.prepareMockRedis(mock) + rediscli.WriteHandle = db + + L := lua.NewState() + + defer L.Close() + + // Set up script + L.Push(lua.LString(tc.script)) + + // Set up keys + keys := L.CreateTable(len(tc.keys), 0) + for _, k := range tc.keys { + keys.Append(lua.LString(k)) + } + + L.Push(keys) + + // Set up args + args := L.CreateTable(len(tc.args), 0) + for _, a := range tc.args { + args.Append(lua.LString(a.(string))) // Annahme, dass args vom Typ string sind + } + + L.Push(args) + + // Call function and check error + numReturned := RedisRunScript(L) + errReturned := L.Get(-2).String() != "nil" + + assert.Equal(t, tc.expectErr, errReturned, "") + assert.Equal(t, 2, numReturned, "") + + // Check result if no error + if !tc.expectErr && numReturned > 0 { + resReturned := L.Get(-1).String() + + assert.Equal(t, tc.expectRes, resReturned, "") + } + + // Check if everything expected was done + assert.NoError(t, mock.ExpectationsWereMet()) + }) + } +}