@@ -195,7 +195,7 @@ TEST_F(ObjectBasicCRUDIntegrationTest, BasicCRUD) {
195195}
196196
197197// / @test Verify the Object CRUD operations with object contexts.
198- TEST_F (ObjectBasicCRUDIntegrationTest, BasicCRUDWithObjectContexts ) {
198+ TEST_F (ObjectBasicCRUDIntegrationTest, BasicInsertAndGetWithObjectContexts ) {
199199 auto client = MakeIntegrationTestClient ();
200200
201201 auto list_object_names = [&client, this ] {
@@ -219,7 +219,55 @@ TEST_F(ObjectBasicCRUDIntegrationTest, BasicCRUDWithObjectContexts) {
219219 bucket_name_, object_name, LoremIpsum (), IfGenerationMatch (0 ),
220220 Projection (" full" ),
221221 WithObjectMetadata (ObjectMetadata ().set_contexts (
222- ObjectContexts ().upsert (" department" , {" engineering" }))));
222+ ObjectContexts ().upsert (" department" , {" engineering" , {}, {}}))));
223+ ASSERT_STATUS_OK (insert_meta);
224+ EXPECT_THAT (list_object_names (), Contains (object_name).Times (1 ));
225+
226+ // Verify the response ObjectMetadata has the custom contexts we set.
227+ StatusOr<ObjectMetadata> get_meta = client.GetObjectMetadata (
228+ bucket_name_, object_name, Generation (insert_meta->generation ()),
229+ Projection (" full" ));
230+ ASSERT_STATUS_OK (get_meta);
231+ EXPECT_TRUE (get_meta->has_contexts ()) << *get_meta;
232+ EXPECT_TRUE (get_meta->contexts ().has_key (" department" )) << *get_meta;
233+ EXPECT_EQ (" engineering" , get_meta->contexts ().custom ().at (" department" ).value )
234+ << *get_meta;
235+ EXPECT_TRUE (IsSet (get_meta->contexts ().custom ().at (" department" ).update_time ))
236+ << *get_meta;
237+ EXPECT_TRUE (IsSet (get_meta->contexts ().custom ().at (" department" ).create_time ))
238+ << *get_meta;
239+
240+ auto status = client.DeleteObject (bucket_name_, object_name);
241+ ASSERT_STATUS_OK (status);
242+ EXPECT_THAT (list_object_names (), Not (Contains (object_name)));
243+ }
244+
245+ // / @test Verify the Object CRUD operations with object contexts.
246+ TEST_F (ObjectBasicCRUDIntegrationTest, BasicUpdateWithObjectContexts) {
247+ auto client = MakeIntegrationTestClient ();
248+
249+ auto list_object_names = [&client, this ] {
250+ std::vector<std::string> names;
251+ for (auto o : client.ListObjects (bucket_name_)) {
252+ EXPECT_STATUS_OK (o);
253+ if (!o) break ;
254+ names.push_back (o->name ());
255+ }
256+ return names;
257+ };
258+
259+ auto object_name = MakeRandomObjectName ();
260+ ASSERT_THAT (list_object_names (), Not (Contains (object_name)))
261+ << " Test aborted. The object <" << object_name << " > already exists."
262+ << " This is unexpected as the test generates a random object name." ;
263+
264+ // Create the object, but only if it does not exist already, inserting
265+ // a custom context {"department": "engineering"}.
266+ StatusOr<ObjectMetadata> insert_meta = client.InsertObject (
267+ bucket_name_, object_name, LoremIpsum (), IfGenerationMatch (0 ),
268+ Projection (" full" ),
269+ WithObjectMetadata (ObjectMetadata ().set_contexts (
270+ ObjectContexts ().upsert (" department" , {" engineering" , {}, {}}))));
223271 ASSERT_STATUS_OK (insert_meta);
224272 EXPECT_THAT (list_object_names (), Contains (object_name).Times (1 ));
225273
@@ -230,21 +278,16 @@ TEST_F(ObjectBasicCRUDIntegrationTest, BasicCRUDWithObjectContexts) {
230278 ASSERT_STATUS_OK (get_meta);
231279 EXPECT_TRUE (get_meta->has_contexts ()) << *get_meta;
232280 EXPECT_TRUE (get_meta->contexts ().has_key (" department" )) << *get_meta;
233- // EXPECT_EQ("engineering",
234- // get_meta->contexts().custom().at("department").value)
235- // << *get_meta;
236- // EXPECT_TRUE(IsSet(get_meta->contexts().custom().at("department").update_time))
237- // << *get_meta;
238- // EXPECT_TRUE(IsSet(get_meta->contexts().custom().at("department").create_time))
239- // << *get_meta;
240281
241282 // Update object with two keys.
242283 ObjectMetadata update = *get_meta;
243- update.set_contexts (ObjectContexts ()
244- .upsert (" department" , {" engineering and research" })
245- .upsert (" region" , {" Asia Pacific" }));
284+ update.set_contexts (
285+ ObjectContexts ()
286+ .upsert (" department" , {" engineering and research" , {}, {}})
287+ .upsert (" region" , {" Asia Pacific" , {}, {}}));
246288 StatusOr<ObjectMetadata> updated_meta = client.UpdateObject (
247- bucket_name_, object_name, update, Projection (" full" ));
289+ bucket_name_, object_name, update, Generation (get_meta->generation ()),
290+ Projection (" full" ));
248291 ASSERT_STATUS_OK (updated_meta);
249292
250293 // Verify the response ObjectMetadata has the updated custom contexts.
@@ -258,22 +301,103 @@ TEST_F(ObjectBasicCRUDIntegrationTest, BasicCRUDWithObjectContexts) {
258301 // updated_meta->contexts().custom().at("region").value)
259302 // << *updated_meta;
260303
261- // Patch object with reset of the "department" key and update of the "region"
262- // key.
263- StatusOr<ObjectMetadata> patched_meta = client.PatchObject (
264- bucket_name_, object_name,
265- ObjectMetadataPatchBuilder ()
266- .ResetContext (" department" )
267- .SetContext (" region" , {" Asia Pacific - Singapore" }),
304+ // This is the test for Object CRUD, we cannot rely on `ScheduleForDelete()`.
305+ auto status = client.DeleteObject (bucket_name_, object_name);
306+ ASSERT_STATUS_OK (status);
307+ EXPECT_THAT (list_object_names (), Not (Contains (object_name)));
308+ }
309+
310+ // / @test Verify the Object CRUD operations with object contexts.
311+ TEST_F (ObjectBasicCRUDIntegrationTest, BasicPatchWithObjectContexts) {
312+ auto client = MakeIntegrationTestClient ();
313+
314+ auto list_object_names = [&client, this ] {
315+ std::vector<std::string> names;
316+ for (auto o : client.ListObjects (bucket_name_)) {
317+ EXPECT_STATUS_OK (o);
318+ if (!o) break ;
319+ names.push_back (o->name ());
320+ }
321+ return names;
322+ };
323+
324+ auto object_name = MakeRandomObjectName ();
325+ ASSERT_THAT (list_object_names (), Not (Contains (object_name)))
326+ << " Test aborted. The object <" << object_name << " > already exists."
327+ << " This is unexpected as the test generates a random object name." ;
328+
329+ // Create the object, but only if it does not exist already, inserting
330+ // a custom context {"department": "engineering"}.
331+ StatusOr<ObjectMetadata> insert_meta = client.InsertObject (
332+ bucket_name_, object_name, LoremIpsum (), IfGenerationMatch (0 ),
333+ Projection (" full" ),
334+ WithObjectMetadata (ObjectMetadata ().set_contexts (
335+ ObjectContexts ().upsert (" department" , {" engineering" , {}, {}}))));
336+ ASSERT_STATUS_OK (insert_meta);
337+ EXPECT_THAT (list_object_names (), Contains (object_name).Times (1 ));
338+
339+ // Verify the response ObjectMetadata has the custom contexts we set.
340+ StatusOr<ObjectMetadata> get_meta = client.GetObjectMetadata (
341+ bucket_name_, object_name, Generation (insert_meta->generation ()),
268342 Projection (" full" ));
343+ ASSERT_STATUS_OK (get_meta);
344+ EXPECT_TRUE (get_meta->has_contexts ()) << *get_meta;
345+ EXPECT_TRUE (get_meta->contexts ().has_key (" department" )) << *get_meta;
346+
347+ StatusOr<ObjectMetadata> patched_meta =
348+ client.PatchObject (bucket_name_, object_name,
349+ ObjectMetadataPatchBuilder ().SetContext (
350+ " region" , {" Asia Pacific - Singapore" }),
351+ Projection (" full" ));
269352 ASSERT_STATUS_OK (patched_meta);
270353
271- // Verify the response ObjectMetadata has the "department" key reset to null
272- // and the "region" key updated.
273354 EXPECT_TRUE (patched_meta->has_contexts ()) << *patched_meta;
274- EXPECT_FALSE (patched_meta->contexts ().has_key (" department" )) << *patched_meta;
355+ EXPECT_TRUE (patched_meta->contexts ().has_key (" department" )) << *patched_meta;
275356 EXPECT_TRUE (patched_meta->contexts ().has_key (" region" )) << *patched_meta;
276357
358+ // This is the test for Object CRUD, we cannot rely on `ScheduleForDelete()`.
359+ auto status = client.DeleteObject (bucket_name_, object_name);
360+ ASSERT_STATUS_OK (status);
361+ EXPECT_THAT (list_object_names (), Not (Contains (object_name)));
362+ }
363+
364+ // / @test Verify the Object CRUD operations with object contexts.
365+ TEST_F (ObjectBasicCRUDIntegrationTest, BasicResetWithObjectContexts) {
366+ auto client = MakeIntegrationTestClient ();
367+
368+ auto list_object_names = [&client, this ] {
369+ std::vector<std::string> names;
370+ for (auto o : client.ListObjects (bucket_name_)) {
371+ EXPECT_STATUS_OK (o);
372+ if (!o) break ;
373+ names.push_back (o->name ());
374+ }
375+ return names;
376+ };
377+
378+ auto object_name = MakeRandomObjectName ();
379+ ASSERT_THAT (list_object_names (), Not (Contains (object_name)))
380+ << " Test aborted. The object <" << object_name << " > already exists."
381+ << " This is unexpected as the test generates a random object name." ;
382+
383+ // Create the object, but only if it does not exist already, inserting
384+ // a custom context {"department": "engineering"}.
385+ StatusOr<ObjectMetadata> insert_meta = client.InsertObject (
386+ bucket_name_, object_name, LoremIpsum (), IfGenerationMatch (0 ),
387+ Projection (" full" ),
388+ WithObjectMetadata (ObjectMetadata ().set_contexts (
389+ ObjectContexts ().upsert (" department" , {" engineering" , {}, {}}))));
390+ ASSERT_STATUS_OK (insert_meta);
391+ EXPECT_THAT (list_object_names (), Contains (object_name).Times (1 ));
392+
393+ // Verify the response ObjectMetadata has the custom contexts we set.
394+ StatusOr<ObjectMetadata> get_meta = client.GetObjectMetadata (
395+ bucket_name_, object_name, Generation (insert_meta->generation ()),
396+ Projection (" full" ));
397+ ASSERT_STATUS_OK (get_meta);
398+ EXPECT_TRUE (get_meta->has_contexts ()) << *get_meta;
399+ EXPECT_TRUE (get_meta->contexts ().has_key (" department" )) << *get_meta;
400+
277401 // Patch object with reset of all contexts.
278402 StatusOr<ObjectMetadata> reset_meta = client.PatchObject (
279403 bucket_name_, object_name, ObjectMetadataPatchBuilder ().ResetContexts (),
0 commit comments