Skip to content

Commit a8c2e9d

Browse files
authored
impl(bigquery): Fixed jobs and tables response for empty use case (#14938)
1 parent 5a7ce3b commit a8c2e9d

File tree

4 files changed

+43
-25
lines changed

4 files changed

+43
-25
lines changed

google/cloud/bigquery/v2/minimal/internal/job_response.cc

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ bool valid_list_format_job(nlohmann::json const& j) {
3737
}
3838

3939
bool valid_jobs_list(nlohmann::json const& j) {
40-
return (j.contains("kind") && j.contains("etag") && j.contains("jobs"));
40+
return (j.contains("kind") && j.contains("etag"));
4141
}
4242

4343
StatusOr<nlohmann::json> parse_json(std::string const& payload) {
@@ -95,9 +95,16 @@ StatusOr<ListJobsResponse> ListJobsResponse::BuildFromHttpResponse(
9595

9696
ListJobsResponse result;
9797
result.http_response = http_response;
98-
9998
result.kind = json->value("kind", "");
10099
result.etag = json->value("etag", "");
100+
101+
if (!(*json).contains("jobs")) {
102+
// For accounts with no jobs, "jobs" json key will not be returned.
103+
// Only "kind" and "etag" keys are returned. Since the server returns
104+
// a 200 in this case, we need to do the same.
105+
return result;
106+
}
107+
101108
result.next_page_token = json->value("nextPageToken", "");
102109

103110
for (auto const& kv : json->at("jobs").items()) {

google/cloud/bigquery/v2/minimal/internal/job_response_test.cc

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,20 @@ TEST(GetJobResponseTest, InvalidJob) {
126126
HasSubstr("Not a valid Json Job object")));
127127
}
128128

129+
TEST(ListJobsResponseTest, NoJobs) {
130+
BigQueryHttpResponse http_response;
131+
http_response.payload =
132+
R"({"kind": "kind-1",
133+
"etag": "tag-1"})";
134+
auto const list_jobs_response =
135+
ListJobsResponse::BuildFromHttpResponse(http_response);
136+
137+
ASSERT_STATUS_OK(list_jobs_response);
138+
EXPECT_FALSE(list_jobs_response->http_response.payload.empty());
139+
EXPECT_EQ(list_jobs_response->kind, "kind-1");
140+
EXPECT_EQ(list_jobs_response->etag, "tag-1");
141+
}
142+
129143
TEST(ListJobsResponseTest, SuccessMultiplePages) {
130144
BigQueryHttpResponse http_response;
131145
http_response.payload =
@@ -225,16 +239,6 @@ TEST(ListJobsResponseTest, InvalidJson) {
225239
HasSubstr("Error parsing Json from response payload")));
226240
}
227241

228-
TEST(ListJobsResponseTest, InvalidJobList) {
229-
BigQueryHttpResponse http_response;
230-
http_response.payload =
231-
R"({"kind": "jkind",
232-
"etag": "jtag"})";
233-
auto const response = ListJobsResponse::BuildFromHttpResponse(http_response);
234-
EXPECT_THAT(response, StatusIs(StatusCode::kInternal,
235-
HasSubstr("Not a valid Json JobList object")));
236-
}
237-
238242
TEST(ListJobsResponseTest, InvalidListFormatJob) {
239243
BigQueryHttpResponse http_response;
240244
http_response.payload =

google/cloud/bigquery/v2/minimal/internal/table_response.cc

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ bool valid_list_format_table(nlohmann::json const& j) {
3636
}
3737

3838
bool valid_tables_list(nlohmann::json const& j) {
39-
return (j.contains("kind") && j.contains("etag") && j.contains("tables"));
39+
return (j.contains("kind") && j.contains("etag"));
4040
}
4141

4242
StatusOr<nlohmann::json> parse_json(std::string const& payload) {
@@ -88,6 +88,11 @@ StatusOr<ListTablesResponse> ListTablesResponse::BuildFromHttpResponse(
8888
result.next_page_token = json->value("nextPageToken", "");
8989
result.total_items = json->value("totalItems", 0);
9090

91+
if (result.total_items == 0) {
92+
// If the dataset is empty, server does not return the "tables" key.
93+
return result;
94+
}
95+
9196
for (auto const& kv : json->at("tables").items()) {
9297
auto const& json_list_format_table_obj = kv.value();
9398
if (!valid_list_format_table(json_list_format_table_obj)) {

google/cloud/bigquery/v2/minimal/internal/table_response_test.cc

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,20 @@ TEST(GetTableResponseTest, InvalidTable) {
6464
HasSubstr("Not a valid Json Table object")));
6565
}
6666

67+
TEST(ListTablesResponseTest, EmptyDatasetNoTables) {
68+
BigQueryHttpResponse http_response;
69+
http_response.payload =
70+
R"({"kind":"kind-1", "etag":"tag-1", "totalItems":0})";
71+
auto const list_tables_response =
72+
ListTablesResponse::BuildFromHttpResponse(http_response);
73+
ASSERT_STATUS_OK(list_tables_response);
74+
EXPECT_FALSE(list_tables_response->http_response.payload.empty());
75+
EXPECT_EQ(list_tables_response->kind, "kind-1");
76+
EXPECT_EQ(list_tables_response->etag, "tag-1");
77+
EXPECT_EQ(list_tables_response->total_items, 0);
78+
EXPECT_THAT(list_tables_response->next_page_token, "");
79+
}
80+
6781
TEST(ListTablesResponseTest, SuccessMultiplePages) {
6882
BigQueryHttpResponse http_response;
6983
auto tables_json_txt =
@@ -133,18 +147,6 @@ TEST(ListTablesResponseTest, InvalidJson) {
133147
HasSubstr("Error parsing Json from response payload")));
134148
}
135149

136-
TEST(ListTablesResponseTest, InvalidTableList) {
137-
BigQueryHttpResponse http_response;
138-
http_response.payload =
139-
R"({"kind": "dkind",
140-
"etag": "dtag"})";
141-
auto const response =
142-
ListTablesResponse::BuildFromHttpResponse(http_response);
143-
EXPECT_THAT(response,
144-
StatusIs(StatusCode::kInternal,
145-
HasSubstr("Not a valid Json TableList object")));
146-
}
147-
148150
TEST(ListTablesResponseTest, InvalidListFormatTable) {
149151
BigQueryHttpResponse http_response;
150152
http_response.payload =

0 commit comments

Comments
 (0)