github.com/googleapis/api-linter@v1.65.2/rules/aip0133/request_required_fields_test.go (about)

     1  // Copyright 2023 Google LLC
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     https://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package aip0133
    16  
    17  import (
    18  	"testing"
    19  
    20  	"github.com/googleapis/api-linter/rules/internal/testutils"
    21  	"github.com/jhump/protoreflect/desc"
    22  )
    23  
    24  func TestRequiredFieldTests(t *testing.T) {
    25  	for _, test := range []struct {
    26  		name                 string
    27  		Fields               string
    28  		problematicFieldName string
    29  		Singular             string
    30  		problems             testutils.Problems
    31  	}{
    32  		{
    33  			"ValidNoExtraFields",
    34  			"",
    35  			"",
    36  			"",
    37  			nil,
    38  		},
    39  		{
    40  			"ValidWithSingularNoExtraFields",
    41  			"",
    42  			"",
    43  			"bookShelf",
    44  			nil,
    45  		},
    46  		{
    47  			"ValidWithSingularAndIdField",
    48  			"string book_shelf_id = 3 [(google.api.field_behavior) = OPTIONAL];",
    49  			"",
    50  			"bookShelf",
    51  			nil,
    52  		},
    53  		{
    54  			"ValidOptionalValidateOnly",
    55  			"string validate_only = 3 [(google.api.field_behavior) = OPTIONAL];",
    56  			"validate_only",
    57  			"",
    58  			nil,
    59  		},
    60  		{
    61  			"InvalidRequiredValidateOnly",
    62  			"bool validate_only = 3 [(google.api.field_behavior) = REQUIRED];",
    63  			"validate_only",
    64  			"",
    65  			testutils.Problems{
    66  				{Message: `Create RPCs must only require fields explicitly described in AIPs, not "validate_only"`},
    67  			},
    68  		},
    69  		{
    70  			"InvalidRequiredUnknownField",
    71  			"bool create_iam = 3 [(google.api.field_behavior) = REQUIRED];",
    72  			"create_iam",
    73  			"",
    74  			testutils.Problems{
    75  				{Message: `Create RPCs must only require fields explicitly described in AIPs, not "create_iam"`},
    76  			},
    77  		},
    78  		{
    79  			"InvalidRequiredUnknownMessageField",
    80  			"Foo foo = 3 [(google.api.field_behavior) = REQUIRED];",
    81  			"foo",
    82  			"",
    83  			testutils.Problems{
    84  				{Message: `Create RPCs must only require fields explicitly described in AIPs, not "foo"`},
    85  			},
    86  		},
    87  	} {
    88  		t.Run(test.name, func(t *testing.T) {
    89  			f := testutils.ParseProto3Tmpl(t, `
    90  				import "google/api/annotations.proto";
    91  				import "google/api/field_behavior.proto";
    92  				import "google/api/resource.proto";
    93  
    94  				service Library {
    95  					rpc CreateBookShelf(CreateBookShelfRequest) returns (BookShelf) {
    96  						option (google.api.http) = {
    97  							delete: "/v1/{name=publishers/*/bookShelves/*}"
    98  						};
    99  					}
   100  				}
   101  
   102  				message BookShelf {
   103  					option (google.api.resource) = {
   104  						type: "library.googleapis.com/BookShelf"
   105  						pattern: "publishers/{publisher}/bookShelves/{book_shelf}"
   106  						singular: "{{.Singular}}"
   107  					};
   108  					string name = 1;
   109  				}
   110  
   111  				message Foo {}
   112  
   113  				message CreateBookShelfRequest {
   114  					string parent = 1 [
   115  						(google.api.field_behavior) = REQUIRED
   116  					];
   117  					BookShelf book_shelf = 2 [
   118  						(google.api.field_behavior) = REQUIRED
   119  					];
   120  					{{.Fields}}
   121  				}
   122  			`, test)
   123  			var dbr desc.Descriptor = f.FindMessage("CreateBookShelfRequest")
   124  			if test.problematicFieldName != "" {
   125  				dbr = f.FindMessage("CreateBookShelfRequest").FindFieldByName(test.problematicFieldName)
   126  			}
   127  			if diff := test.problems.SetDescriptor(dbr).Diff(requestRequiredFields.Lint(f)); diff != "" {
   128  				t.Errorf(diff)
   129  			}
   130  		})
   131  	}
   132  }