github.com/status-im/status-go@v1.1.0/mobile/status_request_log_test.go (about)

     1  package statusgo
     2  
     3  import (
     4  	"encoding/json"
     5  	"fmt"
     6  	"strings"
     7  	"testing"
     8  
     9  	"github.com/stretchr/testify/require"
    10  
    11  	"github.com/status-im/status-go/logutils/requestlog"
    12  	"github.com/status-im/status-go/multiaccounts"
    13  	"github.com/status-im/status-go/multiaccounts/settings"
    14  	"github.com/status-im/status-go/signal"
    15  
    16  	"github.com/ethereum/go-ethereum/log"
    17  )
    18  
    19  func TestRemoveSensitiveInfo(t *testing.T) {
    20  	testCases := []struct {
    21  		name     string
    22  		input    string
    23  		expected string
    24  	}{
    25  		{
    26  			name:     "basic test",
    27  			input:    `{"username":"user1","password":"secret123","mnemonic":"mnemonic123 xyz"}`,
    28  			expected: `{"username":"user1","password":"***","mnemonic":"***"}`,
    29  		},
    30  		{
    31  			name:     "uppercase password field",
    32  			input:    `{"USERNAME":"user1","PASSWORD":"secret123"}`,
    33  			expected: `{"USERNAME":"user1","PASSWORD":"***"}`,
    34  		},
    35  		{
    36  			name:     "password field with spaces",
    37  			input:    `{"username":"user1", "password" : "secret123"}`,
    38  			expected: `{"username":"user1", "password":"***"}`,
    39  		},
    40  		{
    41  			name:     "multiple password fields",
    42  			input:    `{"password":"secret123","data":{"nested_password":"nested_secret"}}`,
    43  			expected: `{"password":"***","data":{"nested_password":"***"}}`,
    44  		},
    45  		{
    46  			name:     "no password field",
    47  			input:    `{"username":"user1","email":"user1@example.com"}`,
    48  			expected: `{"username":"user1","email":"user1@example.com"}`,
    49  		},
    50  	}
    51  
    52  	for _, tc := range testCases {
    53  		t.Run(tc.name, func(t *testing.T) {
    54  			result := removeSensitiveInfo(tc.input)
    55  			if result != tc.expected {
    56  				t.Errorf("Expected: %s, Got: %s", tc.expected, result)
    57  			}
    58  		})
    59  	}
    60  }
    61  
    62  func TestLogAndCall(t *testing.T) {
    63  	// Enable request logging
    64  	requestlog.EnableRequestLogging(true)
    65  
    66  	// Create a mock logger to capture log output
    67  	var logOutput string
    68  	mockLogger := log.New()
    69  	mockLogger.SetHandler(log.FuncHandler(func(r *log.Record) error {
    70  		logOutput += r.Msg + fmt.Sprintf("%s", r.Ctx...)
    71  		return nil
    72  	}))
    73  	requestlog.NewRequestLogger().SetHandler(mockLogger.GetHandler())
    74  
    75  	// Test case 1: Normal execution
    76  	testFunc := func(param string) string {
    77  		return "test result: " + param
    78  	}
    79  	testParam := "test input"
    80  	expectedResult := "test result: test input"
    81  
    82  	result := logAndCallString(testFunc, testParam)
    83  
    84  	// Check the result
    85  	if result != expectedResult {
    86  		t.Errorf("Expected result %s, got %s", expectedResult, result)
    87  	}
    88  
    89  	// Check if the log contains expected information
    90  	expectedLogParts := []string{getShortFunctionName(testFunc), "params", testParam, "resp", expectedResult}
    91  	for _, part := range expectedLogParts {
    92  		if !strings.Contains(logOutput, part) {
    93  			t.Errorf("Log output doesn't contain expected part: %s", part)
    94  		}
    95  	}
    96  
    97  	// Test case 2: Panic -> recovery -> re-panic
    98  	oldRootHandler := log.Root().GetHandler()
    99  	defer log.Root().SetHandler(oldRootHandler)
   100  	log.Root().SetHandler(mockLogger.GetHandler())
   101  	// Clear log output for next test
   102  	logOutput = ""
   103  	e := "test panic"
   104  	panicFunc := func() {
   105  		panic(e)
   106  	}
   107  
   108  	require.PanicsWithValue(t, e, func() {
   109  		logAndCall(panicFunc)
   110  	})
   111  
   112  	// Check if the panic was logged
   113  	if !strings.Contains(logOutput, "panic found in logAndCall") {
   114  		t.Errorf("Log output doesn't contain panic information")
   115  	}
   116  	if !strings.Contains(logOutput, e) {
   117  		t.Errorf("Log output doesn't contain panic message")
   118  	}
   119  	if !strings.Contains(logOutput, "stacktrace") {
   120  		t.Errorf("Log output doesn't contain stacktrace")
   121  	}
   122  }
   123  
   124  func TestGetFunctionName(t *testing.T) {
   125  	fn := getShortFunctionName(initializeApplication)
   126  	require.Equal(t, "initializeApplication", fn)
   127  }
   128  
   129  type testSignalHandler struct {
   130  	receivedSignal string
   131  }
   132  
   133  func (t *testSignalHandler) HandleSignal(data string) {
   134  	t.receivedSignal = data
   135  }
   136  
   137  func TestSetMobileSignalHandler(t *testing.T) {
   138  	// Setup
   139  	handler := &testSignalHandler{}
   140  	SetMobileSignalHandler(handler)
   141  	t.Cleanup(signal.ResetMobileSignalHandler)
   142  
   143  	// Test data
   144  	testAccount := &multiaccounts.Account{Name: "test"}
   145  	testSettings := &settings.Settings{KeyUID: "0x1"}
   146  	testEnsUsernames := json.RawMessage(`{"test": "test"}`)
   147  
   148  	// Action
   149  	signal.SendLoggedIn(testAccount, testSettings, testEnsUsernames, nil)
   150  
   151  	// Assertions
   152  	require.Contains(t, handler.receivedSignal, `"key-uid":"0x1"`, "Signal should contain the correct KeyUID")
   153  	require.Contains(t, handler.receivedSignal, `"name":"test"`, "Signal should contain the correct account name")
   154  	require.Contains(t, handler.receivedSignal, `"ensUsernames":{"test":"test"}`, "Signal should contain the correct ENS usernames")
   155  }