aboutsummaryrefslogtreecommitdiffhomepage
path: root/Firestore/core/test
diff options
context:
space:
mode:
Diffstat (limited to 'Firestore/core/test')
-rw-r--r--Firestore/core/test/firebase/firestore/FSTGoogleTestTests.mm2
-rw-r--r--Firestore/core/test/firebase/firestore/remote/serializer_test.cc112
-rw-r--r--Firestore/core/test/firebase/firestore/util/log_test.cc20
3 files changed, 89 insertions, 45 deletions
diff --git a/Firestore/core/test/firebase/firestore/FSTGoogleTestTests.mm b/Firestore/core/test/firebase/firestore/FSTGoogleTestTests.mm
index c87949a..bb2f836 100644
--- a/Firestore/core/test/firebase/firestore/FSTGoogleTestTests.mm
+++ b/Firestore/core/test/firebase/firestore/FSTGoogleTestTests.mm
@@ -17,8 +17,6 @@
#import <XCTest/XCTest.h>
#import <objc/runtime.h>
-#import "Firestore/Source/Util/FSTAssert.h"
-
#include "gtest/gtest.h"
/**
diff --git a/Firestore/core/test/firebase/firestore/remote/serializer_test.cc b/Firestore/core/test/firebase/firestore/remote/serializer_test.cc
index dd0fae2..999acb8 100644
--- a/Firestore/core/test/firebase/firestore/remote/serializer_test.cc
+++ b/Firestore/core/test/firebase/firestore/remote/serializer_test.cc
@@ -42,6 +42,7 @@
#include "Firestore/core/src/firebase/firestore/util/status.h"
#include "Firestore/core/src/firebase/firestore/util/statusor.h"
#include "Firestore/core/test/firebase/firestore/testutil/testutil.h"
+#include "absl/types/optional.h"
#include "google/protobuf/stubs/common.h"
#include "google/protobuf/util/message_differencer.h"
#include "gtest/gtest.h"
@@ -109,6 +110,13 @@ class SerializerTest : public ::testing::Test {
ExpectDeserializationRoundTrip(key, value, update_time, proto);
}
+ void ExpectNoDocumentDeserializationRoundTrip(
+ const DocumentKey& key,
+ const SnapshotVersion& read_time,
+ const v1beta1::BatchGetDocumentsResponse& proto) {
+ ExpectDeserializationRoundTrip(key, absl::nullopt, read_time, proto);
+ }
+
/**
* Checks the status. Don't use directly; use one of the relevant macros
* instead. eg:
@@ -138,13 +146,21 @@ class SerializerTest : public ::testing::Test {
*
* @param status the expected (failed) status. Only the code() is verified.
*/
- void ExpectFailedStatusDuringDecode(Status status,
- const std::vector<uint8_t>& bytes) {
+ void ExpectFailedStatusDuringFieldValueDecode(
+ Status status, const std::vector<uint8_t>& bytes) {
StatusOr<FieldValue> bad_status = serializer.DecodeFieldValue(bytes);
ASSERT_NOT_OK(bad_status);
EXPECT_EQ(status.code(), bad_status.status().code());
}
+ void ExpectFailedStatusDuringMaybeDocumentDecode(
+ Status status, const std::vector<uint8_t>& bytes) {
+ StatusOr<std::unique_ptr<MaybeDocument>> bad_status =
+ serializer.DecodeMaybeDocument(bytes);
+ ASSERT_NOT_OK(bad_status);
+ EXPECT_EQ(status.code(), bad_status.status().code());
+ }
+
v1beta1::Value ValueProto(nullptr_t) {
std::vector<uint8_t> bytes =
EncodeFieldValue(&serializer, FieldValue::NullValue());
@@ -222,20 +238,21 @@ class SerializerTest : public ::testing::Test {
/**
* Creates entries in the proto that we don't care about.
*
- * We ignore create time in our serializer. We never set it, and never read it
- * (other than to throw it away). But the server could (and probably does) set
- * it, so we need to be able to discard it properly. The ExpectRoundTrip deals
- * with this asymmetry.
+ * We ignore certain fields in our serializer. We never set them, and never
+ * read them (other than to throw them away). But the server could (and
+ * probably does) set them, so we need to be able to discard them properly.
+ * The ExpectRoundTrip deals with this asymmetry.
*
* This method adds these ignored fields to the proto.
*/
void TouchIgnoredBatchGetDocumentsResponseFields(
v1beta1::BatchGetDocumentsResponse* proto) {
+ proto->set_transaction("random bytes");
+
// TODO(rsgowman): This method currently assumes that this is a 'found'
// document. We (probably) will need to adjust this to work with NoDocuments
// too.
v1beta1::Document* doc_proto = proto->mutable_found();
-
google::protobuf::Timestamp* create_time_proto =
doc_proto->mutable_create_time();
create_time_proto->set_seconds(8765);
@@ -279,8 +296,8 @@ class SerializerTest : public ::testing::Test {
bool ok = actual_proto.ParseFromArray(bytes.data(), bytes.size());
EXPECT_TRUE(ok);
- // TODO(rsgowman): Right now, we only support Document (and don't support
- // NoDocument). That should change in the next PR or so.
+ // Note that the client can only serialize Documents (and cannot serialize
+ // NoDocuments)
EXPECT_TRUE(proto.has_found());
// Slight weirdness: When we *encode* a document for sending it to the
@@ -303,8 +320,8 @@ class SerializerTest : public ::testing::Test {
void ExpectDeserializationRoundTrip(
const DocumentKey& key,
- const FieldValue& value,
- const SnapshotVersion& update_time,
+ const absl::optional<FieldValue> value,
+ const SnapshotVersion& version, // either update_time or read_time
const v1beta1::BatchGetDocumentsResponse& proto) {
size_t size = proto.ByteSizeLong();
std::vector<uint8_t> bytes(size);
@@ -316,13 +333,20 @@ class SerializerTest : public ::testing::Test {
std::unique_ptr<MaybeDocument> actual_model =
std::move(actual_model_status).ValueOrDie();
- // TODO(rsgowman): Right now, we only support Document (and don't support
- // NoDocument). That should change in the next PR or so.
- EXPECT_EQ(MaybeDocument::Type::Document, actual_model->type());
- Document* actual_doc_model = static_cast<Document*>(actual_model.get());
EXPECT_EQ(key, actual_model->key());
- EXPECT_EQ(value, actual_doc_model->data());
- EXPECT_EQ(update_time, actual_model->version());
+ EXPECT_EQ(version, actual_model->version());
+ switch (actual_model->type()) {
+ case MaybeDocument::Type::Document: {
+ Document* actual_doc_model = static_cast<Document*>(actual_model.get());
+ EXPECT_EQ(value, actual_doc_model->data());
+ break;
+ }
+ case MaybeDocument::Type::NoDocument:
+ EXPECT_FALSE(value.has_value());
+ break;
+ case MaybeDocument::Type::Unknown:
+ FAIL() << "We somehow created an invalid model object";
+ }
}
std::string message_differences;
@@ -457,7 +481,7 @@ TEST_F(SerializerTest, BadNullValue) {
// Alter the null value from 0 to 1.
Mutate(&bytes[1], /*expected_initial_value=*/0, /*new_value=*/1);
- ExpectFailedStatusDuringDecode(
+ ExpectFailedStatusDuringFieldValueDecode(
Status(FirestoreErrorCode::DataLoss, "ignored"), bytes);
}
@@ -468,7 +492,7 @@ TEST_F(SerializerTest, BadBoolValue) {
// Alter the bool value from 1 to 2. (Value values are 0,1)
Mutate(&bytes[1], /*expected_initial_value=*/1, /*new_value=*/2);
- ExpectFailedStatusDuringDecode(
+ ExpectFailedStatusDuringFieldValueDecode(
Status(FirestoreErrorCode::DataLoss, "ignored"), bytes);
}
@@ -487,7 +511,7 @@ TEST_F(SerializerTest, BadIntegerValue) {
bytes.resize(12);
bytes[11] = 0x7f;
- ExpectFailedStatusDuringDecode(
+ ExpectFailedStatusDuringFieldValueDecode(
Status(FirestoreErrorCode::DataLoss, "ignored"), bytes);
}
@@ -499,7 +523,7 @@ TEST_F(SerializerTest, BadStringValue) {
// used by the encoded tag.)
Mutate(&bytes[2], /*expected_initial_value=*/1, /*new_value=*/5);
- ExpectFailedStatusDuringDecode(
+ ExpectFailedStatusDuringFieldValueDecode(
Status(FirestoreErrorCode::DataLoss, "ignored"), bytes);
}
@@ -510,7 +534,7 @@ TEST_F(SerializerTest, BadTimestampValue_TooLarge) {
// Add some time, which should push us above the maximum allowed timestamp.
Mutate(&bytes[4], 0x82, 0x83);
- ExpectFailedStatusDuringDecode(
+ ExpectFailedStatusDuringFieldValueDecode(
Status(FirestoreErrorCode::DataLoss, "ignored"), bytes);
}
@@ -521,7 +545,7 @@ TEST_F(SerializerTest, BadTimestampValue_TooSmall) {
// Remove some time, which should push us below the minimum allowed timestamp.
Mutate(&bytes[4], 0x92, 0x91);
- ExpectFailedStatusDuringDecode(
+ ExpectFailedStatusDuringFieldValueDecode(
Status(FirestoreErrorCode::DataLoss, "ignored"), bytes);
}
@@ -540,9 +564,9 @@ TEST_F(SerializerTest, BadTag) {
// status. Remove this EXPECT_ANY_THROW statement (and reenable the
// following commented out statement) once the corresponding assert has been
// removed from serializer.cc.
- EXPECT_ANY_THROW(ExpectFailedStatusDuringDecode(
+ EXPECT_ANY_THROW(ExpectFailedStatusDuringFieldValueDecode(
Status(FirestoreErrorCode::DataLoss, "ignored"), bytes));
- // ExpectFailedStatusDuringDecode(
+ // ExpectFailedStatusDuringFieldValueDecode(
// Status(FirestoreErrorCode::DataLoss, "ignored"), bytes);
}
@@ -555,7 +579,7 @@ TEST_F(SerializerTest, TagVarintWiretypeStringMismatch) {
// would do.)
Mutate(&bytes[0], /*expected_initial_value=*/0x08, /*new_value=*/0x0a);
- ExpectFailedStatusDuringDecode(
+ ExpectFailedStatusDuringFieldValueDecode(
Status(FirestoreErrorCode::DataLoss, "ignored"), bytes);
}
@@ -566,7 +590,7 @@ TEST_F(SerializerTest, TagStringWiretypeVarintMismatch) {
// 0x88 represents a string value encoded as a varint.
Mutate(&bytes[0], /*expected_initial_value=*/0x8a, /*new_value=*/0x88);
- ExpectFailedStatusDuringDecode(
+ ExpectFailedStatusDuringFieldValueDecode(
Status(FirestoreErrorCode::DataLoss, "ignored"), bytes);
}
@@ -579,13 +603,13 @@ TEST_F(SerializerTest, IncompleteFieldValue) {
ASSERT_EQ(0x00, bytes[1]);
bytes.pop_back();
- ExpectFailedStatusDuringDecode(
+ ExpectFailedStatusDuringFieldValueDecode(
Status(FirestoreErrorCode::DataLoss, "ignored"), bytes);
}
TEST_F(SerializerTest, IncompleteTag) {
std::vector<uint8_t> bytes;
- ExpectFailedStatusDuringDecode(
+ ExpectFailedStatusDuringFieldValueDecode(
Status(FirestoreErrorCode::DataLoss, "ignored"), bytes);
}
@@ -679,5 +703,35 @@ TEST_F(SerializerTest, EncodesNonEmptyDocument) {
ExpectRoundTrip(key, fields, update_time, proto);
}
+TEST_F(SerializerTest, DecodesNoDocument) {
+ // We can't actually *encode* a NoDocument; the method exposed by the
+ // serializer requires both the document key and contents (as an ObjectValue,
+ // i.e. map.) The contents can be empty, but not missing. As a result, this
+ // test will only verify the ability to decode a NoDocument.
+
+ DocumentKey key = DocumentKey::FromPathString("path/to/the/doc");
+ SnapshotVersion read_time =
+ SnapshotVersion{{/*seconds=*/1234, /*nanoseconds=*/5678}};
+
+ v1beta1::BatchGetDocumentsResponse proto;
+ proto.set_missing(serializer.EncodeKey(key));
+ google::protobuf::Timestamp* read_time_proto = proto.mutable_read_time();
+ read_time_proto->set_seconds(read_time.timestamp().seconds());
+ read_time_proto->set_nanos(read_time.timestamp().nanoseconds());
+
+ ExpectNoDocumentDeserializationRoundTrip(key, read_time, proto);
+}
+
+TEST_F(SerializerTest, DecodeMaybeDocWithoutFoundOrMissingSetShouldFail) {
+ v1beta1::BatchGetDocumentsResponse proto;
+
+ std::vector<uint8_t> bytes(proto.ByteSizeLong());
+ bool status = proto.SerializeToArray(bytes.data(), bytes.size());
+ EXPECT_TRUE(status);
+
+ ExpectFailedStatusDuringMaybeDocumentDecode(
+ Status(FirestoreErrorCode::DataLoss, "ignored"), bytes);
+}
+
// TODO(rsgowman): Test [en|de]coding multiple protos into the same output
// vector.
diff --git a/Firestore/core/test/firebase/firestore/util/log_test.cc b/Firestore/core/test/firebase/firestore/util/log_test.cc
index 973b174..73050ea 100644
--- a/Firestore/core/test/firebase/firestore/util/log_test.cc
+++ b/Firestore/core/test/firebase/firestore/util/log_test.cc
@@ -33,27 +33,19 @@ namespace util {
// defaults write firebase_firestore_util_log_apple_test
// /google/firebase/debug_mode NO
TEST(Log, SetAndGet) {
- LogSetLevel(kLogLevelVerbose);
+ EXPECT_FALSE(LogIsDebugEnabled());
LogSetLevel(kLogLevelDebug);
- EXPECT_EQ(kLogLevelDebug, LogGetLevel());
-
- LogSetLevel(kLogLevelInfo);
- EXPECT_EQ(kLogLevelInfo, LogGetLevel());
+ EXPECT_TRUE(LogIsDebugEnabled());
LogSetLevel(kLogLevelWarning);
- EXPECT_EQ(kLogLevelWarning, LogGetLevel());
-
- LogSetLevel(kLogLevelError);
- EXPECT_EQ(kLogLevelError, LogGetLevel());
+ EXPECT_FALSE(LogIsDebugEnabled());
}
TEST(Log, LogAllKinds) {
- LogDebug("test debug logging %d", 1);
- LogInfo("test info logging %d", 2);
- LogWarning("test warning logging %d", 3);
- LogError("test error logging %d", 4);
- LogMessage(kLogLevelError, "test va-args %s %c %d", "abc", ':', 123);
+ LOG_DEBUG("test debug logging %s", 1);
+ LOG_WARN("test warning logging %s", 3);
+ LOG_DEBUG("test va-args %s %s %s", "abc", std::string{"def"}, 123);
}
} // namespace util