diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 4b04eccd7363176ce589c5b25f1924ba4505cf27..9f430b99a9061139945206b294712c2b8530931c 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -83,7 +83,7 @@ if(LINTING) "--warnings-as-errors=*" "--fix") set(_CMAKE_CXX_CLANG_TIDY_CHECKS - "--checks=*,-fuchsia-*,-llvmlibc-*,-cert-err58-cpp,-cppcoreguidelines-avoid-non-const-global-variables,-cppcoreguidelines-owning-memory,-modernize-use-trailing-return-type,-google-readability-avoid-underscore-in-googletest-name,-cppcoreguidelines-avoid-magic-numbers,-readability-magic-numbers,-cppcoreguidelines-avoid-goto,-hicpp-avoid-goto") + "--checks=*,-fuchsia-*,-llvmlibc-*,-cert-err58-cpp,-cppcoreguidelines-avoid-non-const-global-variables,-cppcoreguidelines-owning-memory,-modernize-use-trailing-return-type,-google-readability-avoid-underscore-in-googletest-name,-cppcoreguidelines-avoid-magic-numbers,-readability-magic-numbers,-cppcoreguidelines-avoid-goto,-hicpp-avoid-goto,-readability-function-cognitive-complexity") endif() else() message(STATUS "LINTING is OFF") diff --git a/test/test_connection.cpp b/test/test_connection.cpp index 8a8cd8f8c59d92c2623ac9f48cd2f8819a38526e..ed1ca1faa5186105c87edb5068916f76ab850882 100644 --- a/test/test_connection.cpp +++ b/test/test_connection.cpp @@ -73,8 +73,7 @@ TEST(test_connection, connection_insecure_authentication_error_anonymous) { EXPECT_THROW(connection.RetrieveVersionInfo(), AuthenticationError); } -// TODO(tf) cognitive complexity > 25 (threshold) -TEST(test_connection, connection_ssl_authentication_error_anonymous) { // NOLINT +TEST(test_connection, connection_ssl_authentication_error_anonymous) { const auto *port_str = caosdb::utility::get_env_var("CAOSDB_SERVER_GRPC_PORT_HTTPS", "8443"); auto port = std::stoi(port_str); @@ -93,9 +92,7 @@ TEST(test_connection, connection_ssl_authentication_error_anonymous) { // NOLINT "succeed. Original error: Please login."); } -// TODO(tf) cognitive complexity > 25 (threshold) -TEST(test_connection, // NOLINT - connection_ssl_authentication_error_wrong_credentials) { // NOLINT +TEST(test_connection, connection_ssl_authentication_error_wrong_credentials) { const auto *port_str = caosdb::utility::get_env_var("CAOSDB_SERVER_GRPC_PORT_HTTPS", "8443"); auto port = std::stoi(port_str); diff --git a/test/test_transaction.cpp b/test/test_transaction.cpp index 3ef5a856feb5a3e30b4f1b45768ef025b8b173be..50a2ba13c22f3126149913d105426922701887b5 100644 --- a/test/test_transaction.cpp +++ b/test/test_transaction.cpp @@ -34,6 +34,7 @@ namespace caosdb::transaction { using caosdb::entity::Entity; using caosdb::entity::MessageCode; using caosdb::entity::Parent; +using caosdb::entity::Property; class test_transaction : public ::testing::Test { protected: @@ -94,8 +95,7 @@ TEST_F(test_transaction, retrieve_non_existing) { MessageCode::ENTITY_DOES_NOT_EXIST); } -// TODO(fspreck) cognitive complexity > 25 (threshold) -TEST_F(test_transaction, insert_delete) { // NOLINT +TEST_F(test_transaction, insert_delete) { const auto &connection = caosdb::connection::ConnectionManager::GetDefaultConnection(); @@ -142,9 +142,7 @@ TEST_F(test_transaction, insert_delete) { // NOLINT EXPECT_FALSE(deleted_entity.HasErrors()); } -// TODO(fspreck) Simplify inserts and deletes once we have -// multi-entity operations, also cognitive complexity > threshold -TEST_F(test_transaction, insert_delete_with_parent) { // NOLINT +TEST_F(test_transaction, insert_delete_with_parent) { const auto &connection = caosdb::connection::ConnectionManager::GetDefaultConnection(); @@ -233,6 +231,167 @@ TEST_F(test_transaction, insert_delete_with_parent) { // NOLINT // TODO(fspreck) Insert a Record with a parent and a Property. Check // for success and delete everything. +TEST(test_transaction, insert_delete_with_property) { + const auto &connection = + caosdb::connection::ConnectionManager::GetDefaultConnection(); + + // Create and insert property + Entity prop_ent; + prop_ent.SetRole("Property"); + prop_ent.SetName("TestProperty"); + prop_ent.SetDatatype("TEXT"); + + auto prop_insertion(connection->CreateTransaction()); + prop_insertion->InsertEntity(&prop_ent); + prop_insertion->ExecuteAsynchronously(); + + auto prop_insert_status = prop_insertion->WaitForIt(); + + ASSERT_TRUE(prop_insert_status.IsTerminated()); + ASSERT_FALSE(prop_insert_status.IsError()); + + const auto &prop_result_set = + dynamic_cast<const UniqueResult &>(prop_insertion->GetResultSet()); + + const auto &inserted_prop = prop_result_set.GetEntity(); + EXPECT_FALSE(inserted_prop.GetId().empty()); + + // create and insert record type with the above property + Property prop_rt; + prop_rt.SetName(prop_ent.GetName()); + prop_rt.SetId(inserted_prop.GetId()); + prop_rt.SetImportance("SUGGESTED"); + + Entity rt; + rt.SetRole("RecordType"); + rt.SetName("TestRT"); + rt.AppendProperty(prop_rt); + + auto rt_insertion(connection->CreateTransaction()); + rt_insertion->InsertEntity(&rt); + rt_insertion->ExecuteAsynchronously(); + + auto rt_insert_status = rt_insertion->WaitForIt(); + + ASSERT_TRUE(rt_insert_status.IsTerminated()); + ASSERT_FALSE(rt_insert_status.IsError()); + + const auto &rt_result_set = + dynamic_cast<const UniqueResult &>(rt_insertion->GetResultSet()); + + const auto &inserted_rt = rt_result_set.GetEntity(); + EXPECT_FALSE(inserted_rt.GetId().empty()); + + // retrieve inserted rt for testing + auto rt_retrieval(connection->CreateTransaction()); + rt_retrieval->RetrieveById(inserted_rt.GetId()); + rt_retrieval->ExecuteAsynchronously(); + + auto rt_retrieve_status = rt_retrieval->WaitForIt(); + ASSERT_TRUE(rt_retrieve_status.IsTerminated()); + ASSERT_FALSE(rt_retrieve_status.IsError()); + + const auto &rt_retrieve_results = + dynamic_cast<const UniqueResult &>(rt_retrieval->GetResultSet()); + + const auto &retrieved_rt = rt_retrieve_results.GetEntity(); + EXPECT_EQ(inserted_rt.GetId(), retrieved_rt.GetId()); + EXPECT_EQ(rt.GetName(), retrieved_rt.GetName()); + EXPECT_EQ(retrieved_rt.GetProperties().Size(), 1); + + const auto &retrieved_prop_rt = retrieved_rt.GetProperties().At(0); + EXPECT_EQ(retrieved_prop_rt.GetName(), prop_ent.GetName()); + EXPECT_EQ(retrieved_prop_rt.GetId(), inserted_prop.GetId()); + EXPECT_EQ(retrieved_prop_rt.GetDatatype(), prop_ent.GetDatatype()); + EXPECT_EQ(retrieved_prop_rt.GetImportance(), prop_rt.GetImportance()); + + // create and insert record of the above record type with a property + // with a value. + Parent parent; + parent.SetName(rt.GetName()); + parent.SetId(inserted_rt.GetId()); + + Property prop_rec; + prop_rec.SetName(prop_ent.GetName()); + prop_rec.SetId(inserted_prop.GetId()); + prop_rec.SetValue("Test"); + + Entity rec; + rec.SetName("TestRec"); + rec.SetRole("Record"); + rec.AppendParent(parent); + rec.AppendProperty(prop_rec); + + auto rec_insertion(connection->CreateTransaction()); + rec_insertion->InsertEntity(&rec); + rec_insertion->ExecuteAsynchronously(); + + auto rec_insert_status = rec_insertion->WaitForIt(); + + ASSERT_TRUE(rec_insert_status.IsTerminated()); + ASSERT_FALSE(rec_insert_status.IsError()); + + const auto &rec_result_set = + dynamic_cast<const UniqueResult &>(rec_insertion->GetResultSet()); + + const auto &inserted_rec = rec_result_set.GetEntity(); + EXPECT_FALSE(inserted_rec.GetId().empty()); + + // Retrieve the record and verify paretn and property + auto rec_retrieval(connection->CreateTransaction()); + rec_retrieval->RetrieveById(inserted_rec.GetId()); + rec_retrieval->ExecuteAsynchronously(); + + auto rec_retrieve_status = rec_retrieval->WaitForIt(); + ASSERT_TRUE(rec_retrieve_status.IsTerminated()); + ASSERT_FALSE(rec_retrieve_status.IsError()); + + const auto &rec_retrieve_results = + dynamic_cast<const UniqueResult &>(rec_retrieval->GetResultSet()); + + const auto &retrieved_rec = rec_retrieve_results.GetEntity(); + EXPECT_EQ(rec.GetName(), retrieved_rec.GetName()); + EXPECT_EQ(inserted_rec.GetId(), retrieved_rec.GetId()); + EXPECT_EQ(retrieved_rec.GetParents().Size(), 1); + EXPECT_EQ(retrieved_rec.GetProperties().Size(), 1); + + const auto &retrieved_parent_rec = retrieved_rec.GetParents().At(0); + EXPECT_EQ(retrieved_parent_rec.GetName(), rt.GetName()); + EXPECT_EQ(retrieved_parent_rec.GetId(), inserted_rt.GetId()); + + const auto &retrieved_prop_rec = retrieved_rec.GetProperties().At(0); + EXPECT_EQ(retrieved_prop_rec.GetName(), prop_ent.GetName()); + EXPECT_EQ(retrieved_prop_rec.GetId(), inserted_prop.GetId()); + EXPECT_EQ(retrieved_prop_rec.GetDatatype(), prop_ent.GetDatatype()); + EXPECT_EQ(retrieved_prop_rec.GetValue(), prop_rec.GetValue()); + + // Delete eveything: First record ... + auto rec_deletion(connection->CreateTransaction()); + rec_deletion->DeleteById(inserted_rec.GetId()); + rec_deletion->ExecuteAsynchronously(); + + auto rec_delete_status = rec_deletion->WaitForIt(); + ASSERT_TRUE(rec_delete_status.IsTerminated()); + ASSERT_FALSE(rec_delete_status.IsError()); + + // ... then parent ... + auto rt_deletion(connection->CreateTransaction()); + rt_deletion->DeleteById(inserted_rt.GetId()); + rt_deletion->ExecuteAsynchronously(); + + auto rt_delete_status = rt_deletion->WaitForIt(); + ASSERT_TRUE(rt_delete_status.IsTerminated()); + ASSERT_FALSE(rt_delete_status.IsError()); + + // ... then property. + auto prop_deletion(connection->CreateTransaction()); + prop_deletion->DeleteById(inserted_prop.GetId()); + prop_deletion->ExecuteAsynchronously(); + + auto prop_delete_status = prop_deletion->WaitForIt(); + ASSERT_TRUE(prop_delete_status.IsTerminated()); + ASSERT_FALSE(prop_delete_status.IsError()); +} TEST_F(test_transaction, test_multi_retrieve) { const auto &connection =