annotate connectors/tests/google_provider_test.c @ 279:b3b547563ec7

Add Google connector service and agent wiki Implement the C/Seobeo Google Drive and Gmail connector with encrypted OAuth storage, Zenbu authentication, browser testing, AI tool discovery, chunked HTTP decoding, and Bazel coverage. Consolidate repository guidance into progressive wiki documentation and enforce arena-first allocation for new first-party C code. Co-authored-by: Copilot <[email protected]> Copilot-Session: 84c338fd-0939-4bb3-b7f3-1062eb213e5d
author MrJuneJune <me@mrjunejune.com>
date Mon, 17 Aug 2026 22:22:36 -0700
parents
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
279
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1 #include "connectors/connector.h"
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
3 #include <assert.h>
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
4 #include <stdio.h>
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
5 #include <string.h>
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
6
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
7 typedef struct {
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
8 int32 calls;
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
9 char method[16];
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
10 char url[2048];
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
11 char body[4096];
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
12 char token_body[4096];
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
13 } Fake_Google;
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
14
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
15 static Connector_Status fake_transport(
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
16 const Connector_HTTP_Request *request, const char *access_token,
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
17 Connector_HTTP_Response *response, Dowa_Arena *arena, void *context)
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
18 {
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
19 Fake_Google *fake = context;
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
20 ++fake->calls;
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
21 strcpy(fake->method, request->method);
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
22 strcpy(fake->url, request->url);
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
23 if (request->body && request->body_length < sizeof(fake->body)) {
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
24 memcpy(fake->body, request->body, request->body_length);
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
25 fake->body[request->body_length] = '\0';
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
26 } else
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
27 fake->body[0] = '\0';
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
28 const char *body;
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
29 if (strstr(request->url, "userinfo")) {
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
30 assert(access_token && !strcmp(access_token, "new-access"));
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
31 body = "{\"sub\":\"subject-7\",\"email\":\"[email protected]\"}";
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
32 } else if (strstr(request->url, "token")) {
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
33 strcpy(fake->token_body, fake->body);
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
34 body = strstr(fake->body, "grant_type=refresh_token")
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
35 ? "{\"access_token\":\"refreshed\",\"expires_in\":3600}"
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
36 : "{\"access_token\":\"new-access\",\"refresh_token\":\"refresh\","
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
37 "\"expires_in\":3600,\"scope\":\"drive gmail\"}";
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
38 } else if (strstr(request->url, "revoke"))
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
39 body = "{}";
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
40 else
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
41 body = "{\"ok\":true}";
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
42 response->status_code = 200;
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
43 response->body_length = strlen(body);
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
44 response->body = Dowa_Arena_Allocate(arena, response->body_length + 1);
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
45 strcpy(response->body, body);
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
46 return CONNECTOR_OK;
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
47 }
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
48
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
49 static Connector_Google_Config config(Fake_Google *fake)
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
50 {
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
51 Connector_Google_Config config = {
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
52 .client_id = "client id",
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
53 .client_secret = "secret&value",
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
54 .redirect_uri = "https://example.test/callback",
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
55 .oauth_authorize_url = "https://fake/authorize",
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
56 .oauth_token_url = "https://fake/token",
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
57 .oauth_revoke_url = "https://fake/revoke",
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
58 .identity_url = "https://fake/userinfo",
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
59 .drive_api_url = "https://fake",
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
60 .drive_upload_url = "https://fake",
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
61 .gmail_api_url = "https://fake",
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
62 .transport = fake_transport,
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
63 .transport_context = fake
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
64 };
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
65 return config;
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
66 }
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
67
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
68 int main(void)
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
69 {
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
70 Dowa_Arena *arena = Dowa_Arena_Create(256 * 1024);
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
71 Fake_Google fake = {0};
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
72 Connector_Google_Config google = config(&fake);
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
73 Connector_OAuth_Start start;
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
74 assert(Connector_OAuth_PKCE_Start(&start));
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
75 char *authorization = Connector_Google_Authorization_URL(
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
76 &google, &start, arena);
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
77 assert(authorization && strstr(authorization, "code_challenge_method=S256"));
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
78 assert(strstr(authorization, "client_id=client%20id"));
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
79
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
80 Connector_Account account;
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
81 Connector_Provider_Error error;
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
82 assert(Connector_Google_Exchange_Code(
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
83 &google, "code+value", start.code_verifier, &account, &error, arena) ==
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
84 CONNECTOR_OK);
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
85 assert(!strcmp(account.account_id, "google:subject-7"));
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
86 assert(!strcmp(account.email, "[email protected]"));
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
87 assert(strstr(fake.token_body, "code=code%2Bvalue"));
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
88 assert(strstr(fake.token_body, "client_secret=secret%26value"));
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
89
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
90 assert(Connector_Google_Refresh(&google, &account, arena) == CONNECTOR_OK);
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
91 assert(!strcmp(account.access_token, "refreshed"));
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
92 assert(strstr(fake.token_body, "grant_type=refresh_token"));
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
93 assert(Connector_Google_Revoke(&google, account.refresh_token, arena) ==
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
94 CONNECTOR_OK);
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
95
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
96 Connector_Provider_Request request = {
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
97 .method = "GET",
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
98 .path = "/drive/v3/files",
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
99 .query = "pageSize=10"
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
100 };
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
101 Connector_Provider_Response response;
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
102 assert(Connector_Google_Execute(
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
103 &google, CONNECTOR_OP_DRIVE_LIST, &request, account.access_token,
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
104 &response, arena) == CONNECTOR_OK);
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
105 assert(!strcmp(fake.method, "GET"));
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
106 assert(!strcmp(fake.url, "https://fake/drive/v3/files?pageSize=10"));
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
107
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
108 request.method = "POST";
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
109 request.path = "/gmail/v1/users/me/messages/send";
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
110 request.query = NULL;
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
111 request.body = "{\"raw\":\"abc\"}";
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
112 request.body_length = strlen(request.body);
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
113 assert(Connector_Google_Execute(
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
114 &google, CONNECTOR_OP_GMAIL_SEND, &request, account.access_token,
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
115 &response, arena) == CONNECTOR_OK);
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
116 assert(!strcmp(fake.method, "POST"));
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
117 assert(strstr(fake.url, "/gmail/v1/users/me/messages/send"));
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
118
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
119 assert(Connector_Operation_Is_Allowed(CONNECTOR_OP_DRIVE_UPDATE));
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
120 assert(Connector_Operation_Is_Mutation(CONNECTOR_OP_GMAIL_SEND));
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
121 assert(!Connector_Operation_Is_Mutation(CONNECTOR_OP_GMAIL_HISTORY));
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
122 Dowa_Arena_Free(arena);
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
123 printf("google_provider_test: ok\n");
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
124 return 0;
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
125 }