@@ -101,6 +101,8 @@ class LocalSerializerTest : public ::testing::Test {
101
101
remote::Serializer remote_serializer;
102
102
local::LocalSerializer serializer;
103
103
104
+ Timestamp write_time_ = Timestamp::Now();
105
+
104
106
template <typename ... Args>
105
107
void ExpectRoundTrip (const Args&... args) {
106
108
// First, serialize model with our (nanopb based) serializer, then
@@ -114,6 +116,75 @@ class LocalSerializerTest : public ::testing::Test {
114
116
ExpectDeserializationRoundTrip (args...);
115
117
}
116
118
119
+ static v1::Write SetProto () {
120
+ v1::Value b_value{};
121
+ *b_value.mutable_string_value () = " b" ;
122
+ v1::Value one_value{};
123
+ one_value.set_integer_value (1 );
124
+
125
+ v1::Write set_proto{};
126
+ *set_proto.mutable_update ()->mutable_name () =
127
+ " projects/p/databases/d/documents/docs/1" ;
128
+ (*set_proto.mutable_update ()->mutable_fields ())[" a" ] = b_value;
129
+ (*set_proto.mutable_update ()->mutable_fields ())[" num" ] = one_value;
130
+ return set_proto;
131
+ }
132
+
133
+ static v1::Write PatchProto () {
134
+ v1::Value b_value{};
135
+ *b_value.mutable_string_value () = " b" ;
136
+ v1::Value one_value{};
137
+ one_value.set_integer_value (1 );
138
+
139
+ v1::Write patch_proto{};
140
+ *patch_proto.mutable_update ()->mutable_name () =
141
+ " projects/p/databases/d/documents/docs/1" ;
142
+ (*patch_proto.mutable_update ()->mutable_fields ())[" a" ] = b_value;
143
+ (*patch_proto.mutable_update ()->mutable_fields ())[" num" ] = one_value;
144
+ patch_proto.mutable_update_mask ()->add_field_paths (" a" );
145
+ patch_proto.mutable_current_document ()->set_exists (true );
146
+ return patch_proto;
147
+ }
148
+
149
+ static v1::Write DeleteProto () {
150
+ v1::Write delete_proto{};
151
+ *delete_proto.mutable_delete_ () = " projects/p/databases/d/documents/docs/1" ;
152
+ return delete_proto;
153
+ }
154
+
155
+ static v1::Write LegacyTransformProto () {
156
+ v1::Write transform_proto{};
157
+
158
+ v1::DocumentTransform::FieldTransform inc_proto1;
159
+ v1::Value inc1_value{};
160
+ inc1_value.set_integer_value (42 );
161
+ inc_proto1.set_field_path (" integer" );
162
+ *inc_proto1.mutable_increment () = inc1_value;
163
+
164
+ v1::DocumentTransform::FieldTransform inc_proto2;
165
+ v1::Value inc2_value{};
166
+ inc2_value.set_double_value (13.37 );
167
+ inc_proto2.set_field_path (" double" );
168
+ *inc_proto2.mutable_increment () = inc2_value;
169
+
170
+ *transform_proto.mutable_transform ()->add_field_transforms () =
171
+ std::move (inc_proto1);
172
+ *transform_proto.mutable_transform ()->add_field_transforms () =
173
+ std::move (inc_proto2);
174
+
175
+ transform_proto.mutable_current_document ()->set_exists (true );
176
+ transform_proto.mutable_transform ()->set_document (
177
+ " projects/p/databases/d/documents/docs/1" );
178
+ return transform_proto;
179
+ }
180
+
181
+ ::google::protobuf::Timestamp WriteTimeProto () {
182
+ ::google::protobuf::Timestamp write_time_proto{};
183
+ write_time_proto.set_seconds (write_time_.seconds ());
184
+ write_time_proto.set_nanos (write_time_.nanoseconds ());
185
+ return write_time_proto;
186
+ }
187
+
117
188
private:
118
189
void ExpectSerializationRoundTrip (
119
190
const MaybeDocument& model,
@@ -138,9 +209,9 @@ class LocalSerializerTest : public ::testing::Test {
138
209
EXPECT_EQ (model, actual_model);
139
210
}
140
211
141
- ByteString EncodeMaybeDocument (local::LocalSerializer* serializer ,
212
+ ByteString EncodeMaybeDocument (local::LocalSerializer* localSerializer ,
142
213
const MaybeDocument& maybe_doc) {
143
- return MakeByteString (serializer ->EncodeMaybeDocument (maybe_doc));
214
+ return MakeByteString (localSerializer ->EncodeMaybeDocument (maybe_doc));
144
215
}
145
216
146
217
void ExpectSerializationRoundTrip (const TargetData& target_data,
@@ -163,10 +234,10 @@ class LocalSerializerTest : public ::testing::Test {
163
234
EXPECT_EQ (target_data, actual_target_data);
164
235
}
165
236
166
- ByteString EncodeTargetData (local::LocalSerializer* serializer ,
237
+ ByteString EncodeTargetData (local::LocalSerializer* localSerializer ,
167
238
const TargetData& target_data) {
168
239
EXPECT_EQ (target_data.purpose (), QueryPurpose::Listen);
169
- return MakeByteString (serializer ->EncodeTargetData (target_data));
240
+ return MakeByteString (localSerializer ->EncodeTargetData (target_data));
170
241
}
171
242
172
243
void ExpectSerializationRoundTrip (
@@ -191,71 +262,129 @@ class LocalSerializerTest : public ::testing::Test {
191
262
EXPECT_EQ (model, actual_mutation_batch);
192
263
}
193
264
194
- ByteString EncodeMutationBatch (local::LocalSerializer* serializer ,
265
+ ByteString EncodeMutationBatch (local::LocalSerializer* localSerializer ,
195
266
const MutationBatch& mutation_batch) {
196
- return MakeByteString (serializer ->EncodeMutationBatch (mutation_batch));
267
+ return MakeByteString (localSerializer ->EncodeMutationBatch (mutation_batch));
197
268
}
198
269
199
270
std::string message_differences;
200
271
MessageDifferencer msg_diff;
201
272
};
202
273
274
+ // TODO(b/174608374): Remove these tests once we perform a schema migration.
275
+ TEST_F (LocalSerializerTest, SetMutationAndTransformMutationAreSquashed) {
276
+ ::firestore::client::WriteBatch batch_proto{};
277
+ batch_proto.set_batch_id (42 );
278
+ *batch_proto.add_writes () = SetProto ();
279
+ *batch_proto.add_writes () = LegacyTransformProto ();
280
+ *batch_proto.mutable_local_write_time () = WriteTimeProto ();
281
+
282
+ ByteString bytes = ProtobufSerialize (batch_proto);
283
+ StringReader reader (bytes);
284
+ auto message = Message<firestore_client_WriteBatch>::TryParse (&reader);
285
+ MutationBatch decoded = serializer.DecodeMutationBatch (&reader, *message);
286
+ ASSERT_EQ (1 , decoded.mutations ().size ());
287
+ ASSERT_EQ (Mutation::Type::Set, decoded.mutations ()[0 ].type ());
288
+ google_firestore_v1_Write encoded =
289
+ remote_serializer.EncodeMutation (decoded.mutations ()[0 ]);
290
+
291
+ google_firestore_v1_Write expected{};
292
+ expected.which_operation = google_firestore_v1_Write_update_tag;
293
+ // TODO: How should I compare these two types?
294
+ EXPECT_EQ (expected, encoded);
295
+ }
296
+
297
+ // TODO(b/174608374): Remove these tests once we perform a schema migration.
298
+ TEST_F (LocalSerializerTest, TransformAndTransformThrowError) {
299
+ ::firestore::client::WriteBatch batch_proto{};
300
+ batch_proto.set_batch_id (42 );
301
+ *batch_proto.add_writes () = LegacyTransformProto ();
302
+ *batch_proto.add_writes () = LegacyTransformProto ();
303
+ *batch_proto.mutable_local_write_time () = WriteTimeProto ();
304
+
305
+ ByteString bytes = ProtobufSerialize (batch_proto);
306
+ StringReader reader (bytes);
307
+ auto message = Message<firestore_client_WriteBatch>::TryParse (&reader);
308
+ EXPECT_ANY_THROW (serializer.DecodeMutationBatch (&reader, *message));
309
+ }
310
+
311
+ // TODO(b/174608374): Remove these tests once we perform a schema migration.
312
+ TEST_F (LocalSerializerTest, OnlyTransformThrowsError) {
313
+ ::firestore::client::WriteBatch batch_proto{};
314
+ batch_proto.set_batch_id (42 );
315
+ *batch_proto.add_writes () = LegacyTransformProto ();
316
+ *batch_proto.mutable_local_write_time () = WriteTimeProto ();
317
+
318
+ ByteString bytes = ProtobufSerialize (batch_proto);
319
+ StringReader reader (bytes);
320
+ auto message = Message<firestore_client_WriteBatch>::TryParse (&reader);
321
+ EXPECT_ANY_THROW (serializer.DecodeMutationBatch (&reader, *message));
322
+ }
323
+
324
+ // TODO(b/174608374): Remove these tests once we perform a schema migration.
325
+ TEST_F (LocalSerializerTest, DeleteAndTransformThrowError) {
326
+ ::firestore::client::WriteBatch batch_proto{};
327
+ batch_proto.set_batch_id (42 );
328
+ *batch_proto.add_writes () = DeleteProto ();
329
+ *batch_proto.add_writes () = LegacyTransformProto ();
330
+ *batch_proto.mutable_local_write_time () = WriteTimeProto ();
331
+
332
+ ByteString bytes = ProtobufSerialize (batch_proto);
333
+ StringReader reader (bytes);
334
+ auto message = Message<firestore_client_WriteBatch>::TryParse (&reader);
335
+ EXPECT_ANY_THROW (serializer.DecodeMutationBatch (&reader, *message));
336
+ }
337
+
338
+ // TODO(b/174608374): Remove these tests once we perform a schema migration.
339
+ TEST_F (LocalSerializerTest, MultipleMutationsAreSquashed) {
340
+ ::firestore::client::WriteBatch batch_proto{};
341
+ batch_proto.set_batch_id (42 );
342
+ *batch_proto.add_writes () = SetProto ();
343
+ *batch_proto.add_writes () = SetProto ();
344
+ *batch_proto.add_writes () = LegacyTransformProto ();
345
+ *batch_proto.add_writes () = DeleteProto ();
346
+ *batch_proto.add_writes () = PatchProto ();
347
+ *batch_proto.add_writes () = LegacyTransformProto ();
348
+ *batch_proto.add_writes () = PatchProto ();
349
+ *batch_proto.mutable_local_write_time () = WriteTimeProto ();
350
+
351
+ ByteString bytes = ProtobufSerialize (batch_proto);
352
+ StringReader reader (bytes);
353
+ auto message = Message<firestore_client_WriteBatch>::TryParse (&reader);
354
+ MutationBatch decoded = serializer.DecodeMutationBatch (&reader, *message);
355
+ ASSERT_EQ (5 , decoded.mutations ().size ());
356
+ }
357
+
203
358
TEST_F (LocalSerializerTest, EncodesMutationBatch) {
204
359
Mutation base =
205
- PatchMutation (Key (" bar/baz " ), WrapObject (" a" , " b" ), FieldMask{Field (" a" )},
360
+ PatchMutation (Key (" docs/1 " ), WrapObject (" a" , " b" ), FieldMask{Field (" a" )},
206
361
Precondition::Exists (true ));
207
362
208
- Mutation set = testutil::SetMutation (" foo/bar " , Map (" a" , " b" , " num" , 1 ));
363
+ Mutation set = testutil::SetMutation (" docs/1 " , Map (" a" , " b" , " num" , 1 ));
209
364
Mutation patch =
210
- PatchMutation (Key (" bar/baz " ), WrapObject (" a" , " b" , " num" , 1 ),
365
+ PatchMutation (Key (" docs/1 " ), WrapObject (" a" , " b" , " num" , 1 ),
211
366
FieldMask{Field (" a" )}, Precondition::Exists (true ));
212
- Mutation del = testutil::DeleteMutation (" baz/quux " );
367
+ Mutation del = testutil::DeleteMutation (" docs/1 " );
213
368
214
- Timestamp write_time = Timestamp::Now ();
215
- MutationBatch model (42 , write_time, {base}, {set, patch, del});
369
+ MutationBatch model (42 , write_time_, {base}, {set, patch, del});
216
370
217
371
v1::Value b_value{};
218
372
*b_value.mutable_string_value () = " b" ;
219
- v1::Value one_value{};
220
- one_value.set_integer_value (1 );
221
373
222
374
v1::Write base_proto{};
223
375
*base_proto.mutable_update ()->mutable_name () =
224
- " projects/p/databases/d/documents/bar/baz " ;
376
+ " projects/p/databases/d/documents/docs/1 " ;
225
377
(*base_proto.mutable_update ()->mutable_fields ())[" a" ] = b_value;
226
378
base_proto.mutable_update_mask ()->add_field_paths (" a" );
227
379
base_proto.mutable_current_document ()->set_exists (true );
228
380
229
- v1::Write set_proto{};
230
- *set_proto.mutable_update ()->mutable_name () =
231
- " projects/p/databases/d/documents/foo/bar" ;
232
- (*set_proto.mutable_update ()->mutable_fields ())[" a" ] = b_value;
233
- (*set_proto.mutable_update ()->mutable_fields ())[" num" ] = one_value;
234
-
235
- v1::Write patch_proto{};
236
- *patch_proto.mutable_update ()->mutable_name () =
237
- " projects/p/databases/d/documents/bar/baz" ;
238
- (*patch_proto.mutable_update ()->mutable_fields ())[" a" ] = b_value;
239
- (*patch_proto.mutable_update ()->mutable_fields ())[" num" ] = one_value;
240
- patch_proto.mutable_update_mask ()->add_field_paths (" a" );
241
- patch_proto.mutable_current_document ()->set_exists (true );
242
-
243
- v1::Write del_proto{};
244
- *del_proto.mutable_delete_ () = " projects/p/databases/d/documents/baz/quux" ;
245
-
246
- ::google::protobuf::Timestamp write_time_proto{};
247
- write_time_proto.set_seconds (write_time.seconds ());
248
- write_time_proto.set_nanos (write_time.nanoseconds ());
249
-
250
381
::firestore::client::WriteBatch batch_proto{};
251
382
batch_proto.set_batch_id (42 );
252
383
*batch_proto.add_base_writes () = base_proto;
253
- *batch_proto.add_writes () = set_proto;
254
- assert (batch_proto.writes (0 ).update ().name () ==
255
- " projects/p/databases/d/documents/foo/bar" );
256
- *batch_proto.add_writes () = patch_proto;
257
- *batch_proto.add_writes () = del_proto;
258
- *batch_proto.mutable_local_write_time () = write_time_proto;
384
+ *batch_proto.add_writes () = SetProto ();
385
+ *batch_proto.add_writes () = PatchProto ();
386
+ *batch_proto.add_writes () = DeleteProto ();
387
+ *batch_proto.mutable_local_write_time () = WriteTimeProto ();
259
388
260
389
ExpectRoundTrip (model, batch_proto);
261
390
}
0 commit comments