...

Source file src/github.com/aws/smithy-go/testing/rest.go

Documentation: github.com/aws/smithy-go/testing

     1  package testing
     2  
     3  import (
     4  	"fmt"
     5  	"net/http"
     6  	"strings"
     7  )
     8  
     9  // HasHeader compares the header values and identifies if the actual header
    10  // set includes all values specified in the expect set. Returns an error if not.
    11  func HasHeader(expect, actual http.Header) error {
    12  	var errs errors
    13  	for key, es := range expect {
    14  		as := actual.Values(key)
    15  		if len(as) == 0 {
    16  			errs = append(errs, fmt.Errorf("expect %v header in %v",
    17  				key, actual))
    18  			continue
    19  		}
    20  
    21  		// Join the list of header values together for consistent
    22  		// comparison between common separated sets, and individual header
    23  		// key/value pairs repeated.
    24  		e := strings.Join(es, ", ")
    25  		a := strings.Join(as, ", ")
    26  		if e != a {
    27  			errs = append(errs, fmt.Errorf("expect %v=%v to match %v",
    28  				key, e, a))
    29  			continue
    30  		}
    31  	}
    32  
    33  	return errs
    34  }
    35  
    36  // AssertHasHeader compares the header values and identifies if the actual
    37  // header set includes all values specified in the expect set. Emits a testing
    38  // error, and returns false if the headers are not equal.
    39  func AssertHasHeader(t T, expect, actual http.Header) bool {
    40  	t.Helper()
    41  
    42  	if err := HasHeader(expect, actual); err != nil {
    43  		for _, e := range err.(errors) {
    44  			t.Error(e)
    45  		}
    46  		return false
    47  	}
    48  	return true
    49  }
    50  
    51  // HasHeaderKeys validates that header set contains all keys expected. Returns
    52  // an error if a header key is not in the header set.
    53  func HasHeaderKeys(keys []string, actual http.Header) error {
    54  	var errs errors
    55  	for _, key := range keys {
    56  		if vs := actual.Values(key); len(vs) == 0 {
    57  			errs = append(errs, fmt.Errorf("expect %v key in %v", key, actual))
    58  			continue
    59  		}
    60  	}
    61  	return errs
    62  }
    63  
    64  // AssertHasHeaderKeys validates that header set contains all keys expected.
    65  // Emits a testing error, and returns false if the headers are not equal.
    66  func AssertHasHeaderKeys(t T, keys []string, actual http.Header) bool {
    67  	t.Helper()
    68  
    69  	if err := HasHeaderKeys(keys, actual); err != nil {
    70  		for _, e := range err.(errors) {
    71  			t.Error(e)
    72  		}
    73  		return false
    74  	}
    75  	return true
    76  }
    77  
    78  // NotHaveHeaderKeys validates that header set does not contains any of the
    79  // keys. Returns an error if a header key is found in the header set.
    80  func NotHaveHeaderKeys(keys []string, actual http.Header) error {
    81  	var errs errors
    82  	for _, k := range keys {
    83  		if vs := actual.Values(k); len(vs) != 0 {
    84  			errs = append(errs, fmt.Errorf("expect %v key not in %v", k, actual))
    85  			continue
    86  		}
    87  	}
    88  	return errs
    89  }
    90  
    91  // AssertNotHaveHeaderKeys validates that header set does not contains any of
    92  // the keys. Emits a testing error, and returns false if the header contains
    93  // the any of the keys equal.
    94  func AssertNotHaveHeaderKeys(t T, keys []string, actual http.Header) bool {
    95  	t.Helper()
    96  
    97  	if err := NotHaveHeaderKeys(keys, actual); err != nil {
    98  		for _, e := range err.(errors) {
    99  			t.Error(e)
   100  		}
   101  		return false
   102  	}
   103  	return true
   104  }
   105  
   106  // QueryItem provides an escaped key and value struct for values from a raw
   107  // query string.
   108  type QueryItem struct {
   109  	Key   string
   110  	Value string
   111  }
   112  
   113  // ParseRawQuery returns a slice of QueryItems extracted from the raw query
   114  // string. The parsed QueryItems preserve escaping of key and values.
   115  //
   116  // All + escape characters are replaced with %20 for consistent escaping
   117  // pattern.
   118  func ParseRawQuery(rawQuery string) (items []QueryItem) {
   119  	for _, item := range strings.Split(rawQuery, `&`) {
   120  		parts := strings.SplitN(item, `=`, 2)
   121  		var value string
   122  		if len(parts) > 1 {
   123  			value = parts[1]
   124  		}
   125  		items = append(items, QueryItem{
   126  			// Go Query encoder escapes space as `+` whereas smithy protocol
   127  			// tests expect `%20`.
   128  			Key:   strings.ReplaceAll(parts[0], `+`, `%20`),
   129  			Value: strings.ReplaceAll(value, `+`, `%20`),
   130  		})
   131  	}
   132  	return items
   133  }
   134  
   135  // HasQuery validates that the expected set of query items are present in
   136  // the actual set. Returns an error if any of the expected set are not found in
   137  // the actual.
   138  func HasQuery(expect, actual []QueryItem) error {
   139  	var errs errors
   140  	for _, item := range expect {
   141  		var found bool
   142  		for _, v := range actual {
   143  			if item.Key == v.Key && item.Value == v.Value {
   144  				found = true
   145  				break
   146  			}
   147  		}
   148  		if !found {
   149  			errs = append(errs, fmt.Errorf("expect %v query item in %v", item, actual))
   150  		}
   151  	}
   152  	return errs
   153  }
   154  
   155  // AssertHasQuery validates that the expected set of query items are
   156  // present in the actual set. Emits a testing error, and returns false if any
   157  // of the expected set are not found in the actual.
   158  func AssertHasQuery(t T, expect, actual []QueryItem) bool {
   159  	t.Helper()
   160  
   161  	if err := HasQuery(expect, actual); err != nil {
   162  		for _, e := range err.(errors) {
   163  			t.Error(e.Error())
   164  		}
   165  		return false
   166  	}
   167  	return true
   168  }
   169  
   170  // HasQueryKeys validates that the actual set of query items contains the keys
   171  // provided. Returns an error if any key is not found.
   172  func HasQueryKeys(keys []string, actual []QueryItem) error {
   173  	var errs errors
   174  	for _, key := range keys {
   175  		var found bool
   176  		for _, v := range actual {
   177  			if key == v.Key {
   178  				found = true
   179  				break
   180  			}
   181  		}
   182  		if !found {
   183  			errs = append(errs, fmt.Errorf("expect %v query key in %v", key, actual))
   184  		}
   185  	}
   186  	return errs
   187  }
   188  
   189  // AssertHasQueryKeys validates that the actual set of query items contains the
   190  // keys provided. Emits a testing error if any key is not found.
   191  func AssertHasQueryKeys(t T, keys []string, actual []QueryItem) bool {
   192  	t.Helper()
   193  
   194  	if err := HasQueryKeys(keys, actual); err != nil {
   195  		for _, e := range err.(errors) {
   196  			t.Error(e)
   197  		}
   198  		return false
   199  	}
   200  	return true
   201  }
   202  
   203  // NotHaveQueryKeys validates that the actual set of query items does not
   204  // contain the keys provided. Returns an error if any key is found.
   205  func NotHaveQueryKeys(keys []string, actual []QueryItem) error {
   206  	var errs errors
   207  	for _, key := range keys {
   208  		for _, v := range actual {
   209  			if key == v.Key {
   210  				errs = append(errs, fmt.Errorf("expect %v query key not in %v",
   211  					key, actual))
   212  				continue
   213  			}
   214  		}
   215  	}
   216  	return errs
   217  }
   218  
   219  // AssertNotHaveQueryKeys validates that the actual set of query items does not
   220  // contains the keys provided. Emits a testing error if any key is found.
   221  func AssertNotHaveQueryKeys(t T, keys []string, actual []QueryItem) bool {
   222  	t.Helper()
   223  
   224  	if err := NotHaveQueryKeys(keys, actual); err != nil {
   225  		for _, e := range err.(errors) {
   226  			t.Error(e)
   227  		}
   228  		return false
   229  	}
   230  	return true
   231  }
   232  

View as plain text