github.com/goravel/framework@v1.13.9/log/formatter/general_test.go (about)

     1  package formatter
     2  
     3  import (
     4  	"strings"
     5  	"testing"
     6  
     7  	"github.com/sirupsen/logrus"
     8  	"github.com/stretchr/testify/assert"
     9  	"github.com/stretchr/testify/suite"
    10  
    11  	configmock "github.com/goravel/framework/contracts/config/mocks"
    12  )
    13  
    14  type GeneralTestSuite struct {
    15  	suite.Suite
    16  	mockConfig *configmock.Config
    17  	entry      *logrus.Entry
    18  }
    19  
    20  func TestGeneralTestSuite(t *testing.T) {
    21  	suite.Run(t, new(GeneralTestSuite))
    22  }
    23  
    24  func (s *GeneralTestSuite) SetupTest() {
    25  	s.mockConfig = &configmock.Config{}
    26  	s.entry = &logrus.Entry{
    27  		Level:   logrus.InfoLevel,
    28  		Message: "Test Message",
    29  	}
    30  }
    31  
    32  func (s *GeneralTestSuite) TestFormat() {
    33  	s.mockConfig.On("GetString", "app.timezone").Return("UTC")
    34  	s.mockConfig.On("GetString", "app.env").Return("test")
    35  
    36  	general := NewGeneral(s.mockConfig)
    37  	tests := []struct {
    38  		name   string
    39  		setup  func()
    40  		assert func()
    41  	}{
    42  		{
    43  			name: "Error in Marshaling",
    44  			setup: func() {
    45  				s.entry.Data = logrus.Fields{
    46  					"root": make(chan int),
    47  				}
    48  			},
    49  			assert: func() {
    50  				formatLog, err := general.Format(s.entry)
    51  				s.NotNil(err)
    52  				s.Nil(formatLog)
    53  			},
    54  		},
    55  		{
    56  			name: "Data is not empty",
    57  			setup: func() {
    58  				s.entry.Data = logrus.Fields{
    59  					"root": map[string]any{
    60  						"code":   "200",
    61  						"domain": "example.com",
    62  						"owner":  "owner",
    63  						"user":   "user1",
    64  					},
    65  				}
    66  			},
    67  			assert: func() {
    68  				formatLog, err := general.Format(s.entry)
    69  				s.Nil(err)
    70  				s.Contains(string(formatLog), "code: \"200\"")
    71  				s.Contains(string(formatLog), "domain: \"example.com\"")
    72  				s.Contains(string(formatLog), "owner: \"owner\"")
    73  				s.Contains(string(formatLog), "user: \"user1\"")
    74  			},
    75  		},
    76  	}
    77  
    78  	for _, test := range tests {
    79  		s.Run(test.name, func() {
    80  			test.setup()
    81  			test.assert()
    82  		})
    83  		s.mockConfig.AssertExpectations(s.T())
    84  	}
    85  }
    86  
    87  func TestFormatData(t *testing.T) {
    88  	var data logrus.Fields
    89  	tests := []struct {
    90  		name   string
    91  		setup  func()
    92  		assert func()
    93  	}{
    94  		{
    95  			name: "Data is empty",
    96  			setup: func() {
    97  				data = logrus.Fields{}
    98  			},
    99  			assert: func() {
   100  				formattedData, err := formatData(data)
   101  				assert.Nil(t, err)
   102  				assert.Empty(t, formattedData)
   103  			},
   104  		},
   105  		{
   106  			name: "Root key is absent",
   107  			setup: func() {
   108  				data = logrus.Fields{
   109  					"key": "value",
   110  				}
   111  			},
   112  			assert: func() {
   113  				formattedData, err := formatData(data)
   114  				assert.NotNil(t, err)
   115  				assert.Empty(t, formattedData)
   116  			},
   117  		},
   118  		{
   119  			name: "Invalid data type",
   120  			setup: func() {
   121  				data = logrus.Fields{
   122  					"root": map[string]any{
   123  						"code":     "123",
   124  						"context":  "sample",
   125  						"domain":   "example.com",
   126  						"hint":     make(chan int), // Invalid data type that will cause an error during value extraction
   127  						"owner":    "owner",
   128  						"request":  map[string]any{"method": "GET", "uri": "http://localhost"},
   129  						"response": map[string]any{"status": 200},
   130  						"tags":     []string{"tag1", "tag2"},
   131  						"user":     "user1",
   132  					},
   133  				}
   134  			},
   135  			assert: func() {
   136  				formattedData, err := formatData(data)
   137  				assert.NotNil(t, err)
   138  				assert.Empty(t, formattedData)
   139  			},
   140  		},
   141  		{
   142  			name: "Data is not empty",
   143  			setup: func() {
   144  				data = logrus.Fields{
   145  					"root": map[string]any{
   146  						"code":   "200",
   147  						"domain": "example.com",
   148  						"owner":  "owner",
   149  						"user":   "user1",
   150  					},
   151  				}
   152  			},
   153  			assert: func() {
   154  				formattedData, err := formatData(data)
   155  				assert.Nil(t, err)
   156  				assert.Contains(t, formattedData, "code: \"200\"")
   157  				assert.Contains(t, formattedData, "domain: \"example.com\"")
   158  				assert.Contains(t, formattedData, "owner: \"owner\"")
   159  				assert.Contains(t, formattedData, "user: \"user1\"")
   160  			},
   161  		},
   162  	}
   163  
   164  	for _, test := range tests {
   165  		t.Run(test.name, func(t *testing.T) {
   166  			test.setup()
   167  			test.assert()
   168  		})
   169  	}
   170  }
   171  
   172  func TestDeleteKey(t *testing.T) {
   173  	tests := []struct {
   174  		name   string
   175  		data   logrus.Fields
   176  		key    string
   177  		assert func()
   178  	}{
   179  		{
   180  			name: "Key is not present in data",
   181  			data: logrus.Fields{
   182  				"key": "value",
   183  			},
   184  			key: "notPresent",
   185  			assert: func() {
   186  				removedData := deleteKey(logrus.Fields{
   187  					"key": "value",
   188  				}, "notPresent")
   189  				assert.Equal(t, logrus.Fields{
   190  					"key": "value",
   191  				}, removedData)
   192  			},
   193  		},
   194  		{
   195  			name: "Key is present in data",
   196  			data: logrus.Fields{
   197  				"key": "value",
   198  			},
   199  			key: "key",
   200  			assert: func() {
   201  				removedData := deleteKey(logrus.Fields{
   202  					"key": "value",
   203  				}, "key")
   204  				assert.Equal(t, logrus.Fields{}, removedData)
   205  			},
   206  		},
   207  	}
   208  
   209  	for _, test := range tests {
   210  		t.Run(test.name, func(t *testing.T) {
   211  			test.assert()
   212  		})
   213  	}
   214  }
   215  
   216  func TestFormatStackTraces(t *testing.T) {
   217  	var stackTraces any
   218  	tests := []struct {
   219  		name   string
   220  		setup  func()
   221  		assert func()
   222  	}{
   223  		{
   224  			name: "StackTraces is nil",
   225  			setup: func() {
   226  				stackTraces = nil
   227  			},
   228  			assert: func() {
   229  				traces, err := formatStackTraces(stackTraces)
   230  				assert.Nil(t, err)
   231  				assert.Equal(t, "trace:\n", traces)
   232  			},
   233  		},
   234  		{
   235  			name: "StackTraces is not nil",
   236  			setup: func() {
   237  				stackTraces = map[string]any{
   238  					"root": map[string]any{
   239  						"message": "error bad request", // root cause
   240  						"stack": []string{
   241  							"main.main:/dummy/examples/logging/example.go:143", // original calling method
   242  							"main.ProcessResource:/dummy/examples/logging/example.go:71",
   243  							"main.(*Request).Validate:/dummy/examples/logging/example.go:29", // location of Wrap call
   244  							"main.(*Request).Validate:/dummy/examples/logging/example.go:28", // location of the root
   245  						},
   246  					},
   247  					"wrap": []map[string]any{
   248  						{
   249  							"message": "received a request with no ID",                                  // additional context
   250  							"stack":   "main.(*Request).Validate:/dummy/examples/logging/example.go:29", // location of Wrap call
   251  						},
   252  					},
   253  				}
   254  			},
   255  			assert: func() {
   256  				traces, err := formatStackTraces(stackTraces)
   257  				assert.Nil(t, err)
   258  				stackTraces := []string{
   259  					"main.main:/dummy/examples/logging/example.go:143",
   260  					"main.ProcessResource:/dummy/examples/logging/example.go:71",
   261  					"main.(*Request).Validate:/dummy/examples/logging/example.go:29",
   262  					"main.(*Request).Validate:/dummy/examples/logging/example.go:28",
   263  				}
   264  				formattedStackTraces := "trace:\n\t" + strings.Join(stackTraces, "\n\t") + "\n"
   265  
   266  				assert.Equal(t, formattedStackTraces, traces)
   267  			},
   268  		},
   269  	}
   270  
   271  	for _, test := range tests {
   272  		t.Run(test.name, func(t *testing.T) {
   273  			test.setup()
   274  			test.assert()
   275  		})
   276  	}
   277  }