github.com/yandex/pandora@v0.5.32/components/providers/scenario/http/postprocessor/var_header_test.go (about)

     1  package postprocessor
     2  
     3  import (
     4  	"fmt"
     5  	"net/http"
     6  	"testing"
     7  
     8  	"github.com/stretchr/testify/assert"
     9  )
    10  
    11  func TestVarHeaderPostprocessor_Process(t *testing.T) {
    12  	tests := []struct {
    13  		name        string
    14  		mappings    map[string]string
    15  		respHeaders map[string]string
    16  		wantMap     map[string]any
    17  		wantErr     bool
    18  	}{
    19  		{
    20  			name: "No Headers",
    21  			mappings: map[string]string{
    22  				"key1": "header1",
    23  				"key2": "header2",
    24  			},
    25  			respHeaders: map[string]string{},
    26  			wantMap:     map[string]any{},
    27  		},
    28  		{
    29  			name:     "No Fields",
    30  			mappings: map[string]string{},
    31  			respHeaders: map[string]string{
    32  				"key1": "header1",
    33  				"key2": "header2"},
    34  			wantMap: nil,
    35  		},
    36  		{
    37  			name: "Error in Fields",
    38  			mappings: map[string]string{
    39  				"key1": "header1||",
    40  			},
    41  			respHeaders: map[string]string{},
    42  			wantMap:     map[string]any{},
    43  			wantErr:     true,
    44  		},
    45  		{
    46  			name: "Headers Exist",
    47  			mappings: map[string]string{
    48  				"key1": "header1",
    49  				"key2": "header2|lower",
    50  				"key3": "header3|upper",
    51  				"key4": "header4|substr(1,3)",
    52  				"key5": "header5|lower|replace(s,x)|substr(1,3)",
    53  				"auth": "Authorization|lower|replace(=,)|substr(6)",
    54  			},
    55  			respHeaders: map[string]string{
    56  				"header1":       "Value1",
    57  				"header2":       "Value2",
    58  				"header3":       "Value3",
    59  				"header4":       "Value4",
    60  				"header5":       "aSdFgHjKl",
    61  				"Authorization": "Basic Ym9zY236Ym9zY28=",
    62  			},
    63  			wantMap: map[string]any{
    64  				"key1": "Value1",
    65  				"key2": "value2",
    66  				"key3": "VALUE3",
    67  				"key4": "al",
    68  				"key5": "xd",
    69  				"auth": "ym9zy236ym9zy28",
    70  			},
    71  		},
    72  	}
    73  
    74  	for _, tt := range tests {
    75  		t.Run(tt.name, func(t *testing.T) {
    76  			p := &VarHeaderPostprocessor{Mapping: tt.mappings}
    77  			resp := &http.Response{
    78  				Header: make(http.Header),
    79  			}
    80  			for k, v := range tt.respHeaders {
    81  				resp.Header.Set(k, v)
    82  			}
    83  
    84  			reqMap, err := p.Process(resp, nil)
    85  			if tt.wantErr {
    86  				assert.Error(t, err)
    87  				return
    88  			}
    89  			assert.NoError(t, err)
    90  			assert.Equal(t, tt.wantMap, reqMap)
    91  		})
    92  	}
    93  }
    94  
    95  func TestVarHeaderPostprocessor_ParseValue(t *testing.T) {
    96  	tests := []struct {
    97  		name                 string
    98  		input                string
    99  		wantVal              string
   100  		wantValAfterModifier string
   101  		wantErr              error
   102  	}{
   103  		{
   104  			name:                 "No Modifier",
   105  			input:                "hello",
   106  			wantVal:              "hello",
   107  			wantValAfterModifier: "hello",
   108  			wantErr:              nil,
   109  		},
   110  		{
   111  			name:                 "Lowercase Modifier",
   112  			input:                "fOOt|lower",
   113  			wantVal:              "fOOt",
   114  			wantValAfterModifier: "foot",
   115  			wantErr:              nil,
   116  		},
   117  		{
   118  			name:                 "Uppercase Modifier",
   119  			input:                "bar|upper",
   120  			wantVal:              "bar",
   121  			wantValAfterModifier: "BAR",
   122  			wantErr:              nil,
   123  		},
   124  		{
   125  			name:                 "Substring Modifier",
   126  			input:                "asdfghjkl|substr(1,3)",
   127  			wantVal:              "asdfghjkl",
   128  			wantValAfterModifier: "sd",
   129  			wantErr:              nil,
   130  		},
   131  		{
   132  			name:                 "Multiple Modifiers",
   133  			input:                "aSdFgHjKl|lower|replace(s,x)|substr(1,3)",
   134  			wantVal:              "aSdFgHjKl",
   135  			wantValAfterModifier: "xd",
   136  			wantErr:              nil,
   137  		},
   138  		{
   139  			name:                 "Multiple Modifiers 2",
   140  			input:                "aPPliCation-JSONbro|lower|replace(-, /)|substr(0, 16)",
   141  			wantVal:              "aPPliCation-JSONbro",
   142  			wantValAfterModifier: "application/json",
   143  			wantErr:              nil,
   144  		},
   145  		{
   146  			name:                 "Invalid Modifier",
   147  			input:                "invalid|unknown",
   148  			wantVal:              "", // The method should return an empty string when the modifier is unknown.
   149  			wantValAfterModifier: "",
   150  			wantErr:              fmt.Errorf("failed to parse modifier unknown: unknown modifier unknown"),
   151  		},
   152  		{
   153  			name:                 "Invalid Modifier Arguments",
   154  			input:                "invalid|substr(abc)",
   155  			wantVal:              "", // The method should return an empty string when the modifier arguments are invalid.
   156  			wantValAfterModifier: "",
   157  			wantErr:              fmt.Errorf("failed to parse modifier substr(abc): substr modifier requires integer as first argument, got abc"),
   158  		},
   159  	}
   160  
   161  	for _, tt := range tests {
   162  		t.Run(tt.name, func(t *testing.T) {
   163  			p := &VarHeaderPostprocessor{}
   164  			value, modifier, err := p.parseValue(tt.input)
   165  			if err != nil {
   166  				assert.EqualError(t, err, tt.wantErr.Error())
   167  				return
   168  			}
   169  			assert.NoError(t, err)
   170  
   171  			assert.Equal(t, tt.wantVal, value)
   172  
   173  			gotModifierVal := modifier(value)
   174  			assert.Equal(t, tt.wantValAfterModifier, gotModifierVal)
   175  
   176  		})
   177  	}
   178  }
   179  
   180  func TestVarHeaderPostprocessor_ParseModifier(t *testing.T) {
   181  	p := &VarHeaderPostprocessor{}
   182  
   183  	tests := []struct {
   184  		name    string
   185  		input   string
   186  		value   string
   187  		want    string
   188  		wantErr error
   189  	}{
   190  		{
   191  			name:    "Lowercase Modifier",
   192  			input:   "lower",
   193  			value:   "HELLO",
   194  			want:    "hello",
   195  			wantErr: nil,
   196  		},
   197  		{
   198  			name:    "Uppercase Modifier",
   199  			input:   "upper",
   200  			value:   "world",
   201  			want:    "WORLD",
   202  			wantErr: nil,
   203  		},
   204  		{
   205  			name:    "Substring Modifier - Normal Case",
   206  			input:   "substr(1,4)",
   207  			value:   "abcdefgh",
   208  			want:    "bcd",
   209  			wantErr: nil,
   210  		},
   211  		{
   212  			name:    "Substring Modifier - Start Index Out of Range (Negative)",
   213  			input:   "substr(-2,4)",
   214  			value:   "abcdefgh",
   215  			want:    "ef",
   216  			wantErr: nil,
   217  		},
   218  		{
   219  			name:    "Substring Modifier - Start Index Greater Than End Index",
   220  			input:   "substr(5,3)",
   221  			value:   "abcdefgh",
   222  			want:    "de",
   223  			wantErr: nil,
   224  		},
   225  		{
   226  			name:    "Substring Modifier - End Index Beyond Length",
   227  			input:   "substr(2,100)",
   228  			value:   "abcdefgh",
   229  			want:    "cdefgh", // End index is beyond the length of the input value, so the modifier should return the substring from index 2 to the end.
   230  			wantErr: nil,
   231  		},
   232  		{
   233  			name:    "Replace Modifier",
   234  			input:   "replace(a,x)",
   235  			value:   "banana",
   236  			want:    "bxnxnx",
   237  			wantErr: nil,
   238  		},
   239  		{
   240  			name:    "Invalid Modifier",
   241  			input:   "invalid",
   242  			value:   "test",
   243  			want:    "", // The modFunc will be nil, so want should be an empty string.
   244  			wantErr: fmt.Errorf("unknown modifier invalid"),
   245  		},
   246  		{
   247  			name:    "Substring Modifier with Invalid Arguments",
   248  			input:   "substr(2)",
   249  			value:   "abc",
   250  			want:    "c",
   251  			wantErr: nil,
   252  		},
   253  		{
   254  			name:    "Replace Modifier with Invalid Arguments",
   255  			input:   "replace(x)",
   256  			value:   "abc",
   257  			want:    "", // The modFunc will be nil, so want should be an empty string.
   258  			wantErr: fmt.Errorf("replace modifier requires 2 arguments"),
   259  		},
   260  	}
   261  
   262  	for _, tt := range tests {
   263  		t.Run(tt.name, func(t *testing.T) {
   264  			modFunc, err := p.parseModifier(tt.input)
   265  
   266  			// If there is an error, modFunc should be nil, and the result should be an empty string.
   267  			if err != nil {
   268  				assert.Nil(t, modFunc)
   269  				assert.EqualError(t, err, tt.wantErr.Error())
   270  				return
   271  			}
   272  
   273  			// If there is no error, apply the modFunc and check the result.
   274  			res := modFunc(tt.value)
   275  			assert.Equal(t, tt.want, res)
   276  			assert.NoError(t, err)
   277  		})
   278  	}
   279  }
   280  
   281  func TestVarHeaderPostprocessor_Substr(t *testing.T) {
   282  	tests := []struct {
   283  		name    string
   284  		args    []string
   285  		value   string
   286  		want    string
   287  		wantErr error
   288  	}{
   289  		{
   290  			name:    "Substring Modifier - Normal Case",
   291  			args:    []string{"1", "4"},
   292  			value:   "abcdefgh",
   293  			want:    "bcd",
   294  			wantErr: nil,
   295  		},
   296  		{
   297  			name:    "Substring Modifier - Start Index Out of Range (Negative)",
   298  			args:    []string{"-2", "4"},
   299  			value:   "abcdefgh",
   300  			want:    "ef", // Start index is negative, so it should count from the end of the string.
   301  			wantErr: nil,
   302  		},
   303  		{
   304  			name:    "Substring Modifier - End Index Out of Range (Negative)",
   305  			args:    []string{"1", "-2"},
   306  			value:   "abcdefgh",
   307  			want:    "bcdef", // End index is negative, so it should count from the end of the string.
   308  			wantErr: nil,
   309  		},
   310  		{
   311  			name:    "Substring Modifier - Start Index Greater Than End Index",
   312  			args:    []string{"5", "3"},
   313  			value:   "abcdefgh",
   314  			want:    "de", // Start index is greater than end index, so the modifier should return the substring from index 3 to 5.
   315  			wantErr: nil,
   316  		},
   317  		{
   318  			name:    "Substring Modifier - End Index Beyond Length",
   319  			args:    []string{"2", "100"},
   320  			value:   "abcdefgh",
   321  			want:    "cdefgh", // End index is beyond the length of the input value, so the modifier should return the substring from index 2 to the end.
   322  			wantErr: nil,
   323  		},
   324  		{
   325  			name:    "Substring Modifier with Invalid Arguments",
   326  			args:    []string{"2"},
   327  			value:   "abc",
   328  			want:    "c",
   329  			wantErr: nil,
   330  		},
   331  		{
   332  			name:    "Substring Modifier with Empty Arguments",
   333  			args:    []string{},
   334  			value:   "abc",
   335  			want:    "", // The modFunc will be nil, so want should be an empty string.
   336  			wantErr: fmt.Errorf("substr modifier requires one or two arguments"),
   337  		},
   338  		{
   339  			name:    "Substring Modifier with Non-Integer Arguments",
   340  			args:    []string{"abc", "xyz"},
   341  			value:   "abc",
   342  			want:    "", // The modFunc will be nil, so want should be an empty string.
   343  			wantErr: fmt.Errorf("substr modifier requires integer as first argument, got abc"),
   344  		},
   345  		{
   346  			name:    "Substring Modifier with Non-Integer second Argument",
   347  			args:    []string{"1", "xyz"},
   348  			value:   "abc",
   349  			want:    "", // The modFunc will be nil, so want should be an empty string.
   350  			wantErr: fmt.Errorf("substr modifier requires integer as second argument, got xyz"),
   351  		},
   352  	}
   353  
   354  	for _, tt := range tests {
   355  		t.Run(tt.name, func(t *testing.T) {
   356  			p := &VarHeaderPostprocessor{}
   357  			modFunc, err := p.substr(tt.args)
   358  			if err != nil {
   359  				assert.Nil(t, modFunc)
   360  				assert.EqualError(t, err, tt.wantErr.Error())
   361  				return
   362  			}
   363  			assert.NoError(t, err)
   364  			assert.Equal(t, tt.want, modFunc(tt.value))
   365  		})
   366  	}
   367  }