diff --git a/test/BUILD b/test/BUILD index b3fe797..b35e3b2 100644 --- a/test/BUILD +++ b/test/BUILD @@ -7,6 +7,27 @@ cc_test( ], ) +cc_library( + name = "mock_feature_provider", + testonly = True, + hdrs = ["mocks/mock_feature_provider.h"], + visibility = ["//test:__pkg__"], + deps = [ + "//include:openfeature_headers", + "@googletest//:gtest", + ], +) + +cc_test( + name = "feature_provider_status_manager_test", + srcs = ["feature_provider_status_manager_test.cpp"], + deps = [ + ":mock_feature_provider", + "//src:feature_provider_status_manager", + "@googletest//:gtest_main", + ], +) + cc_test( name = "noop_provider_test", srcs = ["noop_provider_test.cpp"], diff --git a/test/feature_provider_status_manager_test.cpp b/test/feature_provider_status_manager_test.cpp new file mode 100644 index 0000000..362ec4f --- /dev/null +++ b/test/feature_provider_status_manager_test.cpp @@ -0,0 +1,110 @@ +#include "openfeature/feature_provider_status_manager.h" + +#include + +#include +#include + +#include "absl/status/status.h" +#include "mocks/mock_feature_provider.h" +#include "openfeature/evaluation_context.h" +#include "openfeature/provider_status.h" + +using namespace openfeature; +using ::testing::_; +using ::testing::Return; +using ::testing::Test; +using ::testing::WithParamInterface; + +class FeatureProviderStatusManagerTest : public Test { + protected: + void SetUp() override { + mock_provider_ = std::make_shared(); + absl::StatusOr> result = + FeatureProviderStatusManager::Create(mock_provider_); + ASSERT_TRUE(result.ok()); + manager_ = std::move(result).value(); + ASSERT_NE(manager_, nullptr); + } + + std::shared_ptr mock_provider_; + std::unique_ptr manager_; + EvaluationContext ctx_; +}; + +TEST_F(FeatureProviderStatusManagerTest, CreateWithNullProviderReturnsError) { + auto result = FeatureProviderStatusManager::Create(nullptr); + ASSERT_FALSE(result.ok()); + EXPECT_EQ(result.status().code(), absl::StatusCode::kInvalidArgument); +} + +TEST_F(FeatureProviderStatusManagerTest, CreateWithValidProviderSucceeds) { + EXPECT_EQ(manager_->GetStatus(), ProviderStatus::kNotReady); + EXPECT_EQ(manager_->GetProvider(), mock_provider_); +} + +class FeatureProviderStatusManagerInitTest + : public FeatureProviderStatusManagerTest, + public WithParamInterface> {}; + +TEST_P(FeatureProviderStatusManagerInitTest, InitSetsCorrectStatus) { + auto [provider_init_status, expected_manager_status] = GetParam(); + + EXPECT_CALL(*mock_provider_, Init(_)).WillOnce(Return(provider_init_status)); + manager_->Init(ctx_); + EXPECT_EQ(manager_->GetStatus(), expected_manager_status); +} + +INSTANTIATE_TEST_SUITE_P( + InitStatusTests, FeatureProviderStatusManagerInitTest, + testing::Values( + std::make_tuple(absl::OkStatus(), ProviderStatus::kReady), + std::make_tuple(absl::InternalError("Initialization failed"), + ProviderStatus::kError))); + +class FeatureProviderStatusManagerShutdownTest + : public FeatureProviderStatusManagerTest, + public WithParamInterface {}; + +TEST_P(FeatureProviderStatusManagerShutdownTest, + ShutdownAlwaysSetsStatusToNotReady) { + manager_->SetStatus(ProviderStatus::kReady); + auto provider_shutdown_status = GetParam(); + EXPECT_CALL(*mock_provider_, Shutdown()) + .WillOnce(Return(provider_shutdown_status)); + manager_->Shutdown(); + EXPECT_EQ(manager_->GetStatus(), ProviderStatus::kNotReady); +} + +INSTANTIATE_TEST_SUITE_P( + ShutdownStatusTests, FeatureProviderStatusManagerShutdownTest, + testing::Values(absl::OkStatus(), absl::InternalError("Shutdown failed"))); + +TEST_F(FeatureProviderStatusManagerTest, SetStatusAndGetStatusWorkCorrectly) { + // Verify initial status from SetUp. + ASSERT_EQ(manager_->GetStatus(), ProviderStatus::kNotReady); + + // Define a list of statuses to test. + const std::vector statuses_to_test = { + ProviderStatus::kStale, ProviderStatus::kFatal, ProviderStatus::kReady, + ProviderStatus::kNotReady, ProviderStatus::kError}; + + // Iterate and test each status. + for (const auto& status : statuses_to_test) { + manager_->SetStatus(status); + EXPECT_EQ(manager_->GetStatus(), status); + } +} + +TEST_F(FeatureProviderStatusManagerTest, GetProviderReturnsCorrectProvider) { + // The GetProvider method should return the same instance of the provider + // regardless of the manager's status. + EXPECT_EQ(manager_->GetProvider(), mock_provider_); + manager_->SetStatus(ProviderStatus::kReady); + EXPECT_EQ(manager_->GetProvider(), mock_provider_); +} + +int main(int argc, char** argv) { + testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} \ No newline at end of file diff --git a/test/mocks/mock_feature_provider.h b/test/mocks/mock_feature_provider.h new file mode 100644 index 0000000..6ed49ae --- /dev/null +++ b/test/mocks/mock_feature_provider.h @@ -0,0 +1,27 @@ +#ifndef CPP_SDK_TEST_MOCKS_MOCK_FEATURE_PROVIDER_H_ +#define CPP_SDK_TEST_MOCKS_MOCK_FEATURE_PROVIDER_H_ + +#include + +#include "openfeature/provider.h" + +namespace openfeature { + +// Mock class for FeatureProvider to simulate its behavior in tests. +class MockFeatureProvider : public FeatureProvider { + public: + MOCK_METHOD(Metadata, GetMetadata, (), (const, override)); + MOCK_METHOD(std::unique_ptr, GetBooleanEvaluation, + (std::string_view flag, bool default_value, + const EvaluationContext& ctx), + (override)); + + MOCK_METHOD(absl::Status, Init, (const EvaluationContext& ctx), (override)); + MOCK_METHOD(absl::Status, Shutdown, (), (override)); + + // TODO: Update mock when FeatureProvider interface is completed +}; + +} // namespace openfeature + +#endif // CPP_SDK_TEST_MOCKS_MOCK_FEATURE_PROVIDER_H_ \ No newline at end of file