Skip to content

Commit

Permalink
fix: HTTP body field messages with enums or recursive fields
Browse files Browse the repository at this point in the history
Minor fix for a generating unit tests for methods where the message
that is the body field has a field that is an enum or a recursive
field message type.
  • Loading branch information
software-dov committed Feb 10, 2022
1 parent bd014ff commit 073a4fa
Show file tree
Hide file tree
Showing 2 changed files with 85 additions and 20 deletions.
57 changes: 37 additions & 20 deletions gapic/schema/wrappers.py
Original file line number Diff line number Diff line change
Expand Up @@ -97,29 +97,42 @@ def map(self) -> bool:

@utils.cached_property
def mock_value_original_type(self) -> Union[bool, str, bytes, int, float, Dict[str, Any], List[Any], None]:
# Return messages as dicts and let the message ctor handle the conversion.
if self.message:
if self.map:
# Not worth the hassle, just return an empty map.
return {}
visited_messages = set()

msg_dict = {
f.name: f.mock_value_original_type
for f in self.message.fields.values()
}
def recursive_mock_original_type(field):
if field.message:
# Return messages as dicts and let the message ctor handle the conversion.
if field.message in visited_messages:
return {}

return [msg_dict] if self.repeated else msg_dict
visited_messages.add(field.message)
if field.map:
# Not worth the hassle, just return an empty map.
return {}

answer = self.primitive_mock() or None
msg_dict = {
f.name: recursive_mock_original_type(f)
for f in field.message.fields.values()
}

# If this is a repeated field, then the mock answer should
# be a list.
if self.repeated:
first_item = self.primitive_mock(suffix=1) or None
second_item = self.primitive_mock(suffix=2) or None
answer = [first_item, second_item]
return [msg_dict] if field.repeated else msg_dict

return answer
if field.enum:
# First Truthy value, fallback to the first value
return next((v for v in field.type.values if v.number), field.type.values[0]).number

answer = field.primitive_mock() or None

# If this is a repeated field, then the mock answer should
# be a list.
if field.repeated:
first_item = field.primitive_mock(suffix=1) or None
second_item = field.primitive_mock(suffix=2) or None
answer = [first_item, second_item]

return answer

return recursive_mock_original_type(self)

@utils.cached_property
def mock_value(self) -> str:
Expand Down Expand Up @@ -887,8 +900,12 @@ class HttpRule:
def path_fields(self, method: "Method") -> List[Tuple[Field, str, str]]:
"""return list of (name, template) tuples extracted from uri."""
input = method.input
return [(input.get_field(*match.group("name").split(".")), match.group("name"), match.group("template"))
for match in path_template._VARIABLE_RE.finditer(self.uri)]
return [
(input.get_field(*match.group("name").split(".")),
match.group("name"), match.group("template"))
for match in path_template._VARIABLE_RE.finditer(self.uri)
if match.group("name")
]

def sample_request(self, method: "Method") -> Dict[str, Any]:
"""return json dict for sample request matching the uri template."""
Expand Down
48 changes: 48 additions & 0 deletions tests/fragments/test_non_primitive_body.proto
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,20 @@ service SmallCompute {
post: "/computation/v1/first_name/{first_name}/last_name/{last_name}"
};
};

rpc EnumBody(EnumBodyRequest) returns (EnumBodyResponse) {
option (google.api.http) = {
body: "resource"
post: "/enum_body/v1/names/{name}"
};
}

rpc RecursiveBody(RecursiveBodyRequest) returns (RecursiveBodyResponse) {
option (google.api.http) = {
body: "resource"
post: "/recursive_body/v1/names/{name}"
};
}
}

message SerialNumber {
Expand All @@ -50,4 +64,38 @@ message MethodRequest {

message MethodResponse {
string name = 1;
}

message EnumBodyRequest {
message Resource{
enum Ordering {
UNKNOWN = 0;
CHRONOLOGICAL = 1;
ALPHABETICAL = 2;
DIFFICULTY = 3;
}

Ordering ordering = 1;
}

string name = 1;
Resource resource = 2;
}

message EnumBodyResponse {
string data = 1;
}

message RecursiveBodyRequest {
message Resource {
int32 depth = 1;
Resource child_resource = 2;
}

string name = 1;
Resource resource = 2;
}

message RecursiveBodyResponse {
string data = 1;
}

0 comments on commit 073a4fa

Please sign in to comment.