github.com/hashicorp/vault/sdk@v0.11.0/helper/testhelpers/schema/response_validation_test.go (about)

     1  // Copyright (c) HashiCorp, Inc.
     2  // SPDX-License-Identifier: MPL-2.0
     3  
     4  package schema
     5  
     6  import (
     7  	"testing"
     8  	"time"
     9  
    10  	"github.com/hashicorp/vault/sdk/framework"
    11  )
    12  
    13  func TestValidateResponse(t *testing.T) {
    14  	cases := map[string]struct {
    15  		schema        *framework.Response
    16  		response      map[string]interface{}
    17  		strict        bool
    18  		errorExpected bool
    19  	}{
    20  		"nil schema, nil response, strict": {
    21  			schema:        nil,
    22  			response:      nil,
    23  			strict:        true,
    24  			errorExpected: false,
    25  		},
    26  
    27  		"nil schema, nil response, not strict": {
    28  			schema:        nil,
    29  			response:      nil,
    30  			strict:        false,
    31  			errorExpected: false,
    32  		},
    33  
    34  		"nil schema, good response, strict": {
    35  			schema: nil,
    36  			response: map[string]interface{}{
    37  				"foo": "bar",
    38  			},
    39  			strict:        true,
    40  			errorExpected: false,
    41  		},
    42  
    43  		"nil schema, good response, not strict": {
    44  			schema: nil,
    45  			response: map[string]interface{}{
    46  				"foo": "bar",
    47  			},
    48  			strict:        true,
    49  			errorExpected: false,
    50  		},
    51  
    52  		"nil schema fields, good response, strict": {
    53  			schema: &framework.Response{},
    54  			response: map[string]interface{}{
    55  				"foo": "bar",
    56  			},
    57  			strict:        true,
    58  			errorExpected: false,
    59  		},
    60  
    61  		"nil schema fields, good response, not strict": {
    62  			schema: &framework.Response{},
    63  			response: map[string]interface{}{
    64  				"foo": "bar",
    65  			},
    66  			strict:        true,
    67  			errorExpected: false,
    68  		},
    69  
    70  		"string schema field, string response, strict": {
    71  			schema: &framework.Response{
    72  				Fields: map[string]*framework.FieldSchema{
    73  					"foo": {
    74  						Type: framework.TypeString,
    75  					},
    76  				},
    77  			},
    78  			response: map[string]interface{}{
    79  				"foo": "bar",
    80  			},
    81  			strict:        true,
    82  			errorExpected: false,
    83  		},
    84  
    85  		"string schema field, string response, not strict": {
    86  			schema: &framework.Response{
    87  				Fields: map[string]*framework.FieldSchema{
    88  					"foo": {
    89  						Type: framework.TypeString,
    90  					},
    91  				},
    92  			},
    93  			response: map[string]interface{}{
    94  				"foo": "bar",
    95  			},
    96  			strict:        false,
    97  			errorExpected: false,
    98  		},
    99  
   100  		"string schema not required field, empty response, strict": {
   101  			schema: &framework.Response{
   102  				Fields: map[string]*framework.FieldSchema{
   103  					"foo": {
   104  						Type:     framework.TypeString,
   105  						Required: false,
   106  					},
   107  				},
   108  			},
   109  			response:      map[string]interface{}{},
   110  			strict:        true,
   111  			errorExpected: false,
   112  		},
   113  
   114  		"string schema required field, empty response, strict": {
   115  			schema: &framework.Response{
   116  				Fields: map[string]*framework.FieldSchema{
   117  					"foo": {
   118  						Type:     framework.TypeString,
   119  						Required: true,
   120  					},
   121  				},
   122  			},
   123  			response:      map[string]interface{}{},
   124  			strict:        true,
   125  			errorExpected: true,
   126  		},
   127  
   128  		"string schema required field, empty response, not strict": {
   129  			schema: &framework.Response{
   130  				Fields: map[string]*framework.FieldSchema{
   131  					"foo": {
   132  						Type:     framework.TypeString,
   133  						Required: true,
   134  					},
   135  				},
   136  			},
   137  			response:      map[string]interface{}{},
   138  			strict:        false,
   139  			errorExpected: false,
   140  		},
   141  
   142  		"string schema required field, nil response, strict": {
   143  			schema: &framework.Response{
   144  				Fields: map[string]*framework.FieldSchema{
   145  					"foo": {
   146  						Type:     framework.TypeString,
   147  						Required: true,
   148  					},
   149  				},
   150  			},
   151  			response:      nil,
   152  			strict:        true,
   153  			errorExpected: true,
   154  		},
   155  
   156  		"string schema required field, nil response, not strict": {
   157  			schema: &framework.Response{
   158  				Fields: map[string]*framework.FieldSchema{
   159  					"foo": {
   160  						Type:     framework.TypeString,
   161  						Required: true,
   162  					},
   163  				},
   164  			},
   165  			response:      nil,
   166  			strict:        false,
   167  			errorExpected: false,
   168  		},
   169  
   170  		"empty schema, string response, strict": {
   171  			schema: &framework.Response{
   172  				Fields: map[string]*framework.FieldSchema{},
   173  			},
   174  			response: map[string]interface{}{
   175  				"foo": "bar",
   176  			},
   177  			strict:        true,
   178  			errorExpected: true,
   179  		},
   180  
   181  		"empty schema, string response, not strict": {
   182  			schema: &framework.Response{
   183  				Fields: map[string]*framework.FieldSchema{},
   184  			},
   185  			response: map[string]interface{}{
   186  				"foo": "bar",
   187  			},
   188  			strict:        false,
   189  			errorExpected: false,
   190  		},
   191  
   192  		"time schema, string response, strict": {
   193  			schema: &framework.Response{
   194  				Fields: map[string]*framework.FieldSchema{
   195  					"time": {
   196  						Type:     framework.TypeTime,
   197  						Required: true,
   198  					},
   199  				},
   200  			},
   201  			response: map[string]interface{}{
   202  				"time": "2024-12-11T09:08:07Z",
   203  			},
   204  			strict:        true,
   205  			errorExpected: false,
   206  		},
   207  
   208  		"time schema, string response, not strict": {
   209  			schema: &framework.Response{
   210  				Fields: map[string]*framework.FieldSchema{
   211  					"time": {
   212  						Type:     framework.TypeTime,
   213  						Required: true,
   214  					},
   215  				},
   216  			},
   217  			response: map[string]interface{}{
   218  				"time": "2024-12-11T09:08:07Z",
   219  			},
   220  			strict:        false,
   221  			errorExpected: false,
   222  		},
   223  
   224  		"time schema, time response, strict": {
   225  			schema: &framework.Response{
   226  				Fields: map[string]*framework.FieldSchema{
   227  					"time": {
   228  						Type:     framework.TypeTime,
   229  						Required: true,
   230  					},
   231  				},
   232  			},
   233  			response: map[string]interface{}{
   234  				"time": time.Date(2024, 12, 11, 9, 8, 7, 0, time.UTC),
   235  			},
   236  			strict:        true,
   237  			errorExpected: false,
   238  		},
   239  
   240  		"time schema, time response, not strict": {
   241  			schema: &framework.Response{
   242  				Fields: map[string]*framework.FieldSchema{
   243  					"time": {
   244  						Type:     framework.TypeTime,
   245  						Required: true,
   246  					},
   247  				},
   248  			},
   249  			response: map[string]interface{}{
   250  				"time": time.Date(2024, 12, 11, 9, 8, 7, 0, time.UTC),
   251  			},
   252  			strict:        false,
   253  			errorExpected: false,
   254  		},
   255  
   256  		"empty schema, response has http_raw_body, strict": {
   257  			schema: &framework.Response{
   258  				Fields: map[string]*framework.FieldSchema{},
   259  			},
   260  			response: map[string]interface{}{
   261  				"http_raw_body": "foo",
   262  			},
   263  			strict:        true,
   264  			errorExpected: false,
   265  		},
   266  
   267  		"empty schema, response has http_raw_body, not strict": {
   268  			schema: &framework.Response{
   269  				Fields: map[string]*framework.FieldSchema{},
   270  			},
   271  			response: map[string]interface{}{
   272  				"http_raw_body": "foo",
   273  			},
   274  			strict:        false,
   275  			errorExpected: false,
   276  		},
   277  
   278  		"string schema field, response has non-200 http_status_code, strict": {
   279  			schema: &framework.Response{
   280  				Fields: map[string]*framework.FieldSchema{
   281  					"foo": {
   282  						Type: framework.TypeString,
   283  					},
   284  				},
   285  			},
   286  			response: map[string]interface{}{
   287  				"http_status_code": 304,
   288  			},
   289  			strict:        true,
   290  			errorExpected: false,
   291  		},
   292  
   293  		"string schema field, response has non-200 http_status_code, not strict": {
   294  			schema: &framework.Response{
   295  				Fields: map[string]*framework.FieldSchema{
   296  					"foo": {
   297  						Type: framework.TypeString,
   298  					},
   299  				},
   300  			},
   301  			response: map[string]interface{}{
   302  				"http_status_code": 304,
   303  			},
   304  			strict:        false,
   305  			errorExpected: false,
   306  		},
   307  
   308  		"schema has http_raw_body, strict": {
   309  			schema: &framework.Response{
   310  				Fields: map[string]*framework.FieldSchema{
   311  					"http_raw_body": {
   312  						Type:     framework.TypeString,
   313  						Required: false,
   314  					},
   315  				},
   316  			},
   317  			response: map[string]interface{}{
   318  				"http_raw_body": "foo",
   319  			},
   320  			strict:        true,
   321  			errorExpected: true,
   322  		},
   323  
   324  		"schema has http_raw_body, not strict": {
   325  			schema: &framework.Response{
   326  				Fields: map[string]*framework.FieldSchema{
   327  					"http_raw_body": {
   328  						Type:     framework.TypeString,
   329  						Required: false,
   330  					},
   331  				},
   332  			},
   333  			response: map[string]interface{}{
   334  				"http_raw_body": "foo",
   335  			},
   336  			strict:        false,
   337  			errorExpected: true,
   338  		},
   339  	}
   340  
   341  	for name, tc := range cases {
   342  		name, tc := name, tc
   343  		t.Run(name, func(t *testing.T) {
   344  			t.Parallel()
   345  
   346  			err := validateResponseDataImpl(
   347  				tc.schema,
   348  				tc.response,
   349  				tc.strict,
   350  			)
   351  			if err == nil && tc.errorExpected == true {
   352  				t.Fatalf("expected an error, got nil")
   353  			}
   354  			if err != nil && tc.errorExpected == false {
   355  				t.Fatalf("unexpected error: %v", err)
   356  			}
   357  		})
   358  	}
   359  }