...

Source file src/edge-infra.dev/pkg/sds/interlock/topic/topic_test.go

Documentation: edge-infra.dev/pkg/sds/interlock/topic

     1  package topic
     2  
     3  import (
     4  	"context"
     5  	"errors"
     6  	"net/http"
     7  	"net/http/httptest"
     8  	"testing"
     9  
    10  	"github.com/gin-gonic/gin"
    11  	"github.com/gin-gonic/gin/binding"
    12  	"github.com/go-playground/validator/v10"
    13  	"github.com/stretchr/testify/assert"
    14  	"github.com/stretchr/testify/require"
    15  
    16  	"edge-infra.dev/pkg/lib/fog"
    17  	"edge-infra.dev/pkg/sds/interlock/websocket"
    18  )
    19  
    20  type testState struct {
    21  	Name string
    22  }
    23  
    24  type mockEventHandler struct {
    25  	called int
    26  }
    27  
    28  func (m *mockEventHandler) Send(_ websocket.Event) {
    29  	m.called++
    30  }
    31  
    32  func TestUpdateState(t *testing.T) {
    33  	testCases := map[string]struct {
    34  		uf           UpdateFunc
    35  		updatedName  string
    36  		handlerCalls int
    37  	}{
    38  		"update": {
    39  			updatedName:  "new-name",
    40  			handlerCalls: 1,
    41  		},
    42  		"noupdate": {
    43  			updatedName:  "old-name",
    44  			handlerCalls: 0,
    45  		},
    46  	}
    47  
    48  	for name, tc := range testCases {
    49  		t.Run(name, func(t *testing.T) {
    50  			mockEventHandler := &mockEventHandler{0}
    51  			testTopic := NewTopic(
    52  				"test-topic",
    53  				&testState{
    54  					Name: "old-name",
    55  				},
    56  				nil,
    57  				mockEventHandler,
    58  			)
    59  
    60  			err := testTopic.UpdateState(func(obj interface{}) error {
    61  				state := obj.(*testState)
    62  				state.Name = tc.updatedName
    63  				return nil
    64  			})
    65  			require.NoError(t, err)
    66  
    67  			state, ok := testTopic.state.data.(*testState)
    68  			require.True(t, ok)
    69  
    70  			// test that the event has been sent/not sent
    71  			assert.Equal(t, tc.handlerCalls, mockEventHandler.called)
    72  
    73  			// test that the state has been updated
    74  			assert.Equal(t, tc.updatedName, state.Name)
    75  		})
    76  	}
    77  }
    78  
    79  type AllTypes struct {
    80  	Bool      bool
    81  	String    string
    82  	Int       int
    83  	Slice     []AllTypes
    84  	Map       map[string]AllTypes
    85  	AllTypesP *AllTypes
    86  }
    87  
    88  func TestDeepCopyData(t *testing.T) {
    89  	innerAllTypes := AllTypes{
    90  		Bool:      true,
    91  		String:    "string",
    92  		Int:       1,
    93  		Slice:     make([]AllTypes, 0),
    94  		Map:       make(map[string]AllTypes),
    95  		AllTypesP: nil,
    96  	}
    97  	allTypes := AllTypes{
    98  		Bool:      false,
    99  		String:    "string",
   100  		Int:       1,
   101  		Slice:     []AllTypes{innerAllTypes},
   102  		Map:       map[string]AllTypes{"one": innerAllTypes},
   103  		AllTypesP: &innerAllTypes,
   104  	}
   105  
   106  	allTypesState := &State{
   107  		data: allTypes,
   108  	}
   109  
   110  	got := allTypesState.DeepCopyData()
   111  	assert.Equal(t, allTypes, got)
   112  }
   113  
   114  type mockFieldError struct {
   115  	validator.FieldError
   116  }
   117  
   118  func (fe *mockFieldError) Tag() string {
   119  	return "fe.tag"
   120  }
   121  
   122  func (fe *mockFieldError) Field() string {
   123  	return "fe.field"
   124  }
   125  
   126  func (fe *mockFieldError) Error() string {
   127  	return "error"
   128  }
   129  
   130  func TestHandleBindingError(t *testing.T) {
   131  	myerrors := []validator.FieldError{&mockFieldError{}}
   132  	validationError := validator.ValidationErrors(myerrors)
   133  	sliceValidationError := binding.SliceValidationError{}
   134  	standardError := errors.New("new test error")
   135  
   136  	testCases := map[string]struct {
   137  		inputError error
   138  		errorCode  int
   139  	}{
   140  		"ValidationError": {
   141  			validationError,
   142  			400,
   143  		},
   144  		"SliceValidationError": {
   145  			sliceValidationError,
   146  			400,
   147  		},
   148  		"NotValidationError": {
   149  			standardError,
   150  			500,
   151  		},
   152  	}
   153  
   154  	for name, tc := range testCases {
   155  		t.Run(name, func(t *testing.T) {
   156  			w := httptest.NewRecorder()
   157  			c, _ := gin.CreateTestContext(w)
   158  			c.Request = &http.Request{
   159  				Header: make(http.Header),
   160  				Method: "GET",
   161  			}
   162  
   163  			log := fog.New()
   164  			ctx := context.Background()
   165  
   166  			c.Request = c.Request.WithContext(fog.IntoContext(ctx, log))
   167  
   168  			HandleBindingError(c, tc.inputError)
   169  
   170  			assert.Equal(t, tc.errorCode, w.Code)
   171  		})
   172  	}
   173  }
   174  

View as plain text