github.com/go-email-validator/go-email-validator@v0.0.0-20230409163946-b8b9e6a0552e/pkg/ev/decorator_cache_test.go (about)

     1  package ev
     2  
     3  import (
     4  	"errors"
     5  	"github.com/allegro/bigcache"
     6  	"github.com/eko/gocache/marshaler"
     7  	"github.com/eko/gocache/store"
     8  	"github.com/go-email-validator/go-email-validator/pkg/ev/evcache"
     9  	"github.com/go-email-validator/go-email-validator/pkg/ev/evmail"
    10  	"github.com/go-email-validator/go-email-validator/pkg/ev/evsmtp"
    11  	mockevcache "github.com/go-email-validator/go-email-validator/test/mock/ev/evcache"
    12  	"github.com/golang/mock/gomock"
    13  	"github.com/stretchr/testify/require"
    14  	"net/textproto"
    15  	"reflect"
    16  	"testing"
    17  	"time"
    18  )
    19  
    20  func Test_cacheDecorator_Validate(t *testing.T) {
    21  	ctrl := gomock.NewController(t)
    22  	defer ctrl.Finish()
    23  
    24  	results := make([]ValidationResult, 0)
    25  	key := validEmail.String()
    26  
    27  	type fields struct {
    28  		validator Validator
    29  		cache     func() evcache.Interface
    30  		getKey    CacheKeyGetter
    31  	}
    32  	type args struct {
    33  		email   evmail.Address
    34  		results []ValidationResult
    35  	}
    36  	tests := []struct {
    37  		name       string
    38  		fields     fields
    39  		args       args
    40  		wantResult ValidationResult
    41  	}{
    42  		{
    43  			name: "without cache, error and with set error",
    44  			fields: fields{
    45  				validator: inValidMockValidator,
    46  				cache: func() evcache.Interface {
    47  					cacheMock := mockevcache.NewMockInterface(ctrl)
    48  					cacheMock.EXPECT().Get(key).Return(nil, nil).Times(1)
    49  					cacheMock.EXPECT().Set(key, invalidResult).Return(errorSimple).Times(1)
    50  
    51  					return cacheMock
    52  				},
    53  				getKey: EmailCacheKeyGetter,
    54  			},
    55  			args: args{
    56  				email:   validEmail,
    57  				results: results,
    58  			},
    59  			wantResult: invalidResult,
    60  		},
    61  		{
    62  			name: "without cache and with get error",
    63  			fields: fields{
    64  				validator: validMockValidator,
    65  				cache: func() evcache.Interface {
    66  					cacheMock := mockevcache.NewMockInterface(ctrl)
    67  					cacheMock.EXPECT().Get(key).Return(nil, errorSimple).Times(1)
    68  					cacheMock.EXPECT().Set(key, validResult).Return(nil).Times(1)
    69  
    70  					return cacheMock
    71  				},
    72  				getKey: nil,
    73  			},
    74  			args: args{
    75  				email:   validEmail,
    76  				results: results,
    77  			},
    78  			wantResult: validResult,
    79  		},
    80  		{
    81  			name: "with cache",
    82  			fields: fields{
    83  				validator: validMockValidator,
    84  				cache: func() evcache.Interface {
    85  					cacheMock := mockevcache.NewMockInterface(ctrl)
    86  					cacheMock.EXPECT().Get(key).Return(&validResult, nil).Times(1)
    87  
    88  					return cacheMock
    89  				},
    90  				getKey: EmailCacheKeyGetter,
    91  			},
    92  			args: args{
    93  				email:   validEmail,
    94  				results: nil,
    95  			},
    96  			wantResult: validResult,
    97  		},
    98  	}
    99  	for _, tt := range tests {
   100  		t.Run(tt.name, func(t *testing.T) {
   101  			c := NewCacheDecorator(tt.fields.validator, tt.fields.cache(), tt.fields.getKey)
   102  			if gotResult := c.Validate(NewInput(tt.args.email), tt.args.results...); !reflect.DeepEqual(gotResult, tt.wantResult) {
   103  				t.Errorf("Validate() = %v, want %v", gotResult, tt.wantResult)
   104  			}
   105  		})
   106  	}
   107  }
   108  
   109  func Test_cacheDecorator_GetDeps(t *testing.T) {
   110  	deps := []ValidatorName{OtherValidator}
   111  
   112  	type fields struct {
   113  		validator Validator
   114  		cache     evcache.Interface
   115  		getKey    CacheKeyGetter
   116  	}
   117  	tests := []struct {
   118  		name   string
   119  		fields fields
   120  		want   []ValidatorName
   121  	}{
   122  		{
   123  			name: "return deps",
   124  			fields: fields{
   125  				validator: mockValidator{deps: deps},
   126  			},
   127  			want: deps,
   128  		},
   129  	}
   130  	for _, tt := range tests {
   131  		t.Run(tt.name, func(t *testing.T) {
   132  			c := &cacheDecorator{
   133  				validator: tt.fields.validator,
   134  				cache:     tt.fields.cache,
   135  				getKey:    tt.fields.getKey,
   136  			}
   137  			if got := c.GetDeps(); !reflect.DeepEqual(got, tt.want) {
   138  				t.Errorf("GetDeps() = %v, want %v", got, tt.want)
   139  			}
   140  		})
   141  	}
   142  }
   143  
   144  func TestEmailCacheKeyGetter(t *testing.T) {
   145  	type args struct {
   146  		email   evmail.Address
   147  		results []ValidationResult
   148  	}
   149  	tests := []struct {
   150  		name string
   151  		args args
   152  		want interface{}
   153  	}{
   154  		{
   155  			name: "success",
   156  			args: args{
   157  				email:   validEmail,
   158  				results: nil,
   159  			},
   160  			want: validEmail.String(),
   161  		},
   162  	}
   163  	for _, tt := range tests {
   164  		t.Run(tt.name, func(t *testing.T) {
   165  			if got := EmailCacheKeyGetter(NewInput(tt.args.email), tt.args.results...); !reflect.DeepEqual(got, tt.want) {
   166  				t.Errorf("EmailCacheKeyGetter() = %v, want %v", got, tt.want)
   167  			}
   168  		})
   169  	}
   170  }
   171  
   172  func TestDomainCacheKeyGetter(t *testing.T) {
   173  	type args struct {
   174  		email evmail.Address
   175  	}
   176  	tests := []struct {
   177  		name string
   178  		args args
   179  		want interface{}
   180  	}{
   181  		{
   182  			name: "success",
   183  			args: args{
   184  				email: validEmail,
   185  			},
   186  			want: validEmail.Domain(),
   187  		},
   188  	}
   189  	for _, tt := range tests {
   190  		t.Run(tt.name, func(t *testing.T) {
   191  			if got := DomainCacheKeyGetter(NewInput(tt.args.email)); !reflect.DeepEqual(got, tt.want) {
   192  				t.Errorf("DomainCacheKeyGetter() = %v, want %v", got, tt.want)
   193  			}
   194  		})
   195  	}
   196  }
   197  
   198  type customErr struct{}
   199  
   200  func (customErr) Error() string {
   201  	return "customErr"
   202  }
   203  
   204  var cacheErrs = []error{
   205  	//error(&customErr{}), TODO find way to marshal and unmarshal all interfaces
   206  	NewDepsError(),
   207  	evsmtp.NewError(1, &textproto.Error{Code: 505, Msg: "msg1"}),
   208  	evsmtp.NewError(1, errors.New("msg2")),
   209  }
   210  var validatorResult = NewResult(true, cacheErrs, cacheErrs, OtherValidator)
   211  
   212  func Test_Cache(t *testing.T) {
   213  	bigCacheClient, err := bigcache.NewBigCache(bigcache.DefaultConfig(1 * time.Second))
   214  	require.Nil(t, err)
   215  	bigCacheStore := store.NewBigcache(bigCacheClient, nil)
   216  
   217  	marshal := marshaler.New(bigCacheStore)
   218  
   219  	cache := evcache.NewCacheMarshaller(marshal, func() interface{} {
   220  		return new(ValidationResult)
   221  	}, nil)
   222  
   223  	key := "key"
   224  
   225  	err = cache.Set(key, validatorResult)
   226  	require.Nil(t, err)
   227  
   228  	gotInterface, err := cache.Get(key)
   229  	require.Nil(t, err)
   230  	got := *gotInterface.(*ValidationResult)
   231  	require.Equal(t, validatorResult, got)
   232  }