#include <cstdint>
#include <filesystem>  //NOLINT
#include <memory>
#include <string>
#include <system_error>  // NOLINT
#include <utility>
#include <vector>

#include <gmock/gmock.h>
#include <gtest/gtest.h>
#include "absl/functional/any_invocable.h"
#include "http_request.hpp"
#include "http_response.hpp"
#include "async_resp.hpp"
#include "dbus_utility.hpp"
#include "managers.hpp"
#include "test/redfish-core/lib/snapshot_fixture.hpp"
#include <nlohmann/json.hpp>
#include "managed_store.hpp"
#include "managed_store_types.hpp"
#include "test/g3/mock_managed_store.hpp"
#include "test/g3/mock_managed_store_test.hpp"

namespace redfish
{
namespace
{

using ::dbus::utility::DBusPropertiesMap;
using ::dbus::utility::DbusVariantType;
using ::dbus::utility::MapperGetSubTreeResponse;
using ::dbus::utility::MapperServiceMap;
using ::managedStore::KeyType;
using ::managedStore::ManagedType;
using ::managedStore::SimulateFailedAsyncPostDbusCallThreadSafeWithEmptyValueAction;
using ::managedStore::ValueType;

constexpr char kClassType[] = "Temperature";
constexpr char kSensor[] = "sensor0";
constexpr double kInput = 43.0;
constexpr double kOutput = 4000.0;
constexpr double kSetpoint = 65.0;
constexpr uint8_t kTestData = 15;

// std::shared_ptr<ValueType> CreateMockSubtreeResponse()
// {
//     MapperGetSubTreeResponse mockSubtreeResponse{{std::make_pair(
//         "/xyz/openbmc_project/inventory/system/component/BMC_flash",
//         MapperServiceMap{{std::make_pair(
//             "xyz.openbmc_project.EntityManager",
//             std::vector<std::string>{
//                 "xyz.openbmc_project.Inventory.Decorator.LocationCode"})}})}};
//     return managedStore::MockManagedStoreTest::CreateValueType(
//         std::move(mockSubtreeResponse));
// }

// TODO(edwarddl): Uncomment after handleManagerGet is updated
// TEST_F(SnapshotFixture, handleManagerGetTest)
// {
//     KeyType key(ManagedType::kManagedSubtree,
//                 "/xyz/openbmc_project/inventory", 0,
//                 {"xyz.openbmc_project.Inventory.Item.Bmc"});
//     ASSERT_TRUE(
//         dynamic_cast<managedStore::MockSerializedManagedObjectStore*>(
//             managedStore::GetManagedObjectStore())
//             ->upsertMockObjectIntoManagedStore(
//                 key, CreateMockSubtreeResponse())
//             .ok());
//     handleManagerGet(app_, CreateRequest(), share_async_resp_);
//
//     RunIoUntilDone();
//
//     nlohmann::json& json = share_async_resp_->res.jsonValue;
//
//     LOG(INFO) << json.dump(2);
//     EXPECT_EQ(json["@odata.id"], "/redfish/v1/Managers/bmc");
//     EXPECT_EQ(json["Location"]["PartLocation"]["ServiceLabel"], "BMC");
//     EXPECT_EQ(json["Location"]["PartLocation"]["LocationType"], "Embedded");
//     EXPECT_EQ(json["Location"]["PartLocationContext"], "DC_SCM");
//     EXPECT_EQ(json["Location"]["Oem"]["Google"]["EmbeddedLocationContext"],
//               "openbmc_manager");
//     EXPECT_EQ(json["Links"]["ManagerForServers@odata.count"], 1);
//     EXPECT_EQ(json["Links"]["ManagerForServers"][0]["@odata.id"],
//               "/redfish/v1/Systems/system");
//     EXPECT_EQ(share_async_resp_->res.result(),
//               boost::beast::http::status::ok);
// }

std::shared_ptr<ValueType> CreatePidDebugInfoProperty()
{
    DBusPropertiesMap pidDebugInfoProperty{
        {std::make_pair("ClassType", DbusVariantType(kClassType))},
        {std::make_pair("Input", DbusVariantType(kInput))},
        {std::make_pair("Leader", DbusVariantType(kSensor))},
        {std::make_pair("Output", DbusVariantType(kOutput))},
        {std::make_pair("Setpoint", DbusVariantType(kSetpoint))},
        {std::make_pair("TestData", DbusVariantType(kTestData))}};
    return managedStore::MockManagedStoreTest::CreateValueType(
        std::move(pidDebugInfoProperty));
}

TEST_F(SnapshotFixture, updateZoneLeaderInfoGetNull)
{
    const std::string zoneIndex = "0";
    const std::string name = "Zone_0";
    const std::string leader = "sensor_PID";
    const std::string pidDebugInfoPath =
        "/xyz/openbmc_project/settings/fanctrl/zone" + zoneIndex + "/" + leader;

    auto response = std::make_shared<bmcweb::AsyncResp>();
    nlohmann::json& json = response->res.jsonValue;
    managedStore::ManagedObjectStoreContext context(response);

    // Test for null dbus response
    updateZoneLeaderInfo(response, zoneIndex, name, leader, context);

    RunIoUntilDone();

    EXPECT_TRUE(
        json["Oem"]["OpenBmc"]["Fan"]["FanZones"][name]["Leader"]["ClassType"]
            .is_null());
    EXPECT_TRUE(
        json["Oem"]["OpenBmc"]["Fan"]["FanZones"][name]["Leader"]["Input"]
            .is_null());
    EXPECT_TRUE(
        json["Oem"]["OpenBmc"]["Fan"]["FanZones"][name]["Leader"]["Output"]
            .is_null());
    EXPECT_TRUE(
        json["Oem"]["OpenBmc"]["Fan"]["FanZones"][name]["Leader"]["Sensor"]
            .is_null());
    EXPECT_TRUE(
        json["Oem"]["OpenBmc"]["Fan"]["FanZones"][name]["Leader"]["Setpoint"]
            .is_null());
}

TEST_F(SnapshotFixture, updateZoneLeaderInfoSuccess)
{
    const std::string zoneIndex = "0";
    const std::string name = "Zone_0";
    const std::string leader = "sensor_PID";
    const std::string pidDebugInfoPath =
        "/xyz/openbmc_project/settings/fanctrl/zone" + zoneIndex + "/" + leader;

    auto response = std::make_shared<bmcweb::AsyncResp>();
    nlohmann::json& json = response->res.jsonValue;
    managedStore::ManagedObjectStoreContext context(response);

    // kManagedPropertyMap
    KeyType key(ManagedType::kManagedPropertyMap,
                "xyz.openbmc_project.State.FanCtrl", pidDebugInfoPath,
                "xyz.openbmc_project.Debug.Pid.ThermalPower");

    ASSERT_TRUE(dynamic_cast<managedStore::MockSerializedManagedObjectStore*>(
                    managedStore::GetManagedObjectStore())
                    ->upsertMockObjectIntoManagedStore(
                        key, CreatePidDebugInfoProperty())
                    .ok());

    updateZoneLeaderInfo(response, zoneIndex, name, leader, context);

    RunIoUntilDone();

    EXPECT_EQ(
        json["Oem"]["OpenBmc"]["Fan"]["FanZones"][name]["Leader"]["ClassType"],
        kClassType);
    EXPECT_EQ(
        json["Oem"]["OpenBmc"]["Fan"]["FanZones"][name]["Leader"]["Input"],
        kInput);
    EXPECT_EQ(
        json["Oem"]["OpenBmc"]["Fan"]["FanZones"][name]["Leader"]["Sensor"],
        kSensor);
    EXPECT_EQ(
        json["Oem"]["OpenBmc"]["Fan"]["FanZones"][name]["Leader"]["Output"],
        kOutput);
    EXPECT_EQ(
        json["Oem"]["OpenBmc"]["Fan"]["FanZones"][name]["Leader"]["Setpoint"],
        kSetpoint);
    EXPECT_EQ(
        json["Oem"]["OpenBmc"]["Fan"]["FanZones"][name]["Leader"]["TestData"],
        "n/a");
}

TEST_F(SnapshotFixture, PostManagerResetActionGood)
{
    // using expected call to mitigate the memory issue in valgrind
    // https://b.corp.google.com/issues/416295689
    // https://b.corp.google.com/issues/416608762
    EXPECT_CALL(
        *dynamic_cast<managedStore::MockSerializedManagedObjectStore*>(
            managedStore::GetManagedObjectStore()),
        PostDbusCallToIoContextThreadSafe(
            testing::_,
            testing::An<
                absl::AnyInvocable<void(const boost::system::error_code&)>&&>(),
            "xyz.openbmc_project.State.Chassis",
            testing::An<const std::string&>(),
            "org.freedesktop.DBus.Properties", "Set",
            "xyz.openbmc_project.State.Chassis", "RequestedPowerTransition",
            dbus::utility::DbusVariantType(
                "xyz.openbmc_project.State.Chassis.Transition.PowerCycle")))
        .WillOnce(
            managedStore::SimulateSuccessfulAsyncPostDbusCallThreadSafeAction::
                SimulateSuccessfulAsyncPostDbusCall());

    handlePostManagerResetAction(
        app_, CreateRequest("{\"ResetType\":\"TrayPowerCycle\"} "),
        share_async_resp_);

    RunIoUntilDone();

    EXPECT_EQ(share_async_resp_->res.result(), boost::beast::http::status::ok);
}

TEST_F(SnapshotFixture, PostManagerResetActionBadResetType)
{
    handlePostManagerResetAction(
        app_, CreateRequest("{\"ResetType\":\"Typo\"} "), share_async_resp_);

    RunIoUntilDone();

    EXPECT_EQ(share_async_resp_->res.result(),
              boost::beast::http::status::bad_request);
}

TEST_F(SnapshotFixture, handleManagerResetActionInfoAllowableValues)
{
    handleManagerResetActionInfo(app_, CreateRequest(""), share_async_resp_);

    RunIoUntilDone();

    EXPECT_EQ(share_async_resp_->res.result(), boost::beast::http::status::ok);

    auto allowable_values =
        share_async_resp_->res.jsonValue["Parameters"][0]["AllowableValues"];
    EXPECT_THAT(allowable_values,
                testing::ElementsAre("GracefulRestart", "ForceRestart",
                                     "TrayPowerCycle"));
}

// TODO(edwarddl): Uncomment after handleManagerGet is updated
// TEST_F(SnapshotFixture, handleManagerGetMultiSystem)
// {
//     KeyType key(ManagedType::kManagedSubtreePaths, "/", 0,
//                 {"xyz.openbmc_project.Inventory.Item.System"});
//
//     std::vector<std::string> path = {
//         "/xyz/system1",
//         "/xyz/system2",
//     };
//     std::shared_ptr<ValueType> test_value = CreateValueType(path);
//     ASSERT_TRUE(dynamic_cast<managedStore::MockSerializedManagedObjectStore*>(
//                     managedStore::GetManagedObjectStore())
//                     ->upsertMockObjectIntoManagedStore(key, test_value)
//                     .ok());
//
//     handleManagerGet(app_, CreateRequest(), share_async_resp_);
//
//     RunIoUntilDone();
//
//     nlohmann::json& json = share_async_resp_->res.jsonValue;
//
//     EXPECT_EQ(json["Links"]["ManagerForServers@odata.count"], 2);
//     EXPECT_EQ(json["Links"]["ManagerForServers"][0]["@odata.id"],
//               "/redfish/v1/Systems/system1");
//     EXPECT_EQ(json["Links"]["ManagerForServers"][1]["@odata.id"],
//               "/redfish/v1/Systems/system2");
//     EXPECT_EQ(share_async_resp_->res.result(),
//               boost::beast::http::status::ok);
// }

TEST_F(SnapshotFixture, handleManagerGetFruDeviceOemLink) {
  std::error_code ec;
  auto origPath = std::filesystem::current_path(ec);
  std::filesystem::current_path(std::filesystem::temp_directory_path(ec), ec);

  handleManagerGet(app_, CreateRequest(), share_async_resp_, "bmc");

  RunIoUntilDone();

  std::filesystem::current_path(origPath, ec);

  nlohmann::json& json = share_async_resp_->res.jsonValue;
  EXPECT_EQ(json["Oem"]["Google"]["FruDevice"]["@odata.id"],
            "/redfish/v1/Managers/bmc/Oem/Google/FruDevice");
}

TEST_F(SnapshotFixture, handleFruDeviceGet) {
  handleFruDeviceGet(app_, CreateRequest(), share_async_resp_);

  RunIoUntilDone();

  nlohmann::json& json = share_async_resp_->res.jsonValue;
  EXPECT_EQ(json, nlohmann::json::parse(R"({
    "@odata.id": "/redfish/v1/Managers/bmc/Oem/Google/FruDevice",
    "@odata.type": "#GoogleFruDevice.v1_0_0.GoogleFruDeviceService",
    "Id": "FruDevice",
    "IpmiFrus": {
      "@odata.id": "/redfish/v1/Managers/bmc/Oem/Google/FruDevice/IpmiFrus"
    },
    "Name": "Google FRU Device Service",
    "RawEeproms": {
      "@odata.id": "/redfish/v1/Managers/bmc/Oem/Google/FruDevice/RawEeproms"
    }
  })"));
  EXPECT_EQ(share_async_resp_->res.result(), boost::beast::http::status::ok);
}

TEST_F(SnapshotFixture, handleIpmiFruCollectionGet) {
  KeyType key(ManagedType::kManagedSubtreePaths,
              "/xyz/openbmc_project/FruDevice", 0,
              {"xyz.openbmc_project.FruDevice"});

  std::vector<std::string> paths = {
      "/xyz/openbmc_project/FruDevice/TestFru1",
      "/xyz/openbmc_project/FruDevice/TestFru2",
  };
  ASSERT_TRUE(
      dynamic_cast<managedStore::MockSerializedManagedObjectStore*>(
          managedStore::GetManagedObjectStore())
          ->upsertMockObjectIntoManagedStore(
              key, managedStore::MockManagedStoreTest::CreateValueType(paths))
          .ok());

  handleIpmiFruCollectionGet(app_, CreateRequest(), share_async_resp_);

  RunIoUntilDone();

  nlohmann::json& json = share_async_resp_->res.jsonValue;
  EXPECT_EQ(json, nlohmann::json::parse(R"({
    "@odata.id": "/redfish/v1/Managers/bmc/Oem/Google/FruDevice/IpmiFrus",
    "@odata.type": "#GoogleFruDevice.v1_0_0.GoogleIpmiFruCollection",
    "Id": "IpmiFrus",
    "Members": [
      {
        "@odata.id": "/redfish/v1/Managers/bmc/Oem/Google/FruDevice/IpmiFrus/TestFru1"
      },
      {
        "@odata.id": "/redfish/v1/Managers/bmc/Oem/Google/FruDevice/IpmiFrus/TestFru2"
      }
    ],
    "Members@odata.count": 2,
    "Name": "Google IPMI FRU Collection"
  })"));
  EXPECT_EQ(share_async_resp_->res.result(), boost::beast::http::status::ok);
}

TEST_F(SnapshotFixture, handleRawEepromCollectionGet) {
  KeyType key(ManagedType::kManagedSubtreePaths,
              "/xyz/openbmc_project/FruDevice", 0,
              {"xyz.openbmc_project.Inventory.Item.I2CDevice"});

  std::vector<std::string> paths = {
      "/xyz/openbmc_project/FruDevice/Eeprom1",
  };
  ASSERT_TRUE(
      dynamic_cast<managedStore::MockSerializedManagedObjectStore*>(
          managedStore::GetManagedObjectStore())
          ->upsertMockObjectIntoManagedStore(
              key, managedStore::MockManagedStoreTest::CreateValueType(paths))
          .ok());

  handleRawEepromCollectionGet(app_, CreateRequest(), share_async_resp_);

  RunIoUntilDone();

  nlohmann::json& json = share_async_resp_->res.jsonValue;
  EXPECT_EQ(json, nlohmann::json::parse(R"({
    "@odata.id": "/redfish/v1/Managers/bmc/Oem/Google/FruDevice/RawEeproms",
    "@odata.type": "#GoogleFruDevice.v1_0_0.GoogleRawEepromCollection",
    "Id": "RawEeproms",
    "Members": [
      {
        "@odata.id": "/redfish/v1/Managers/bmc/Oem/Google/FruDevice/RawEeproms/Eeprom1"
      }
    ],
    "Members@odata.count": 1,
    "Name": "Google Raw EEPROM Collection"
  })"));
  EXPECT_EQ(share_async_resp_->res.result(), boost::beast::http::status::ok);
}

TEST(ToTitleCaseTest, ConvertsPropertyNamesToTitleCase) {
  EXPECT_EQ(toTitleCase("BOARD_PRODUCT_NAME"), "BoardProductName");
  EXPECT_EQ(toTitleCase("BUS"), "Bus");
  EXPECT_EQ(toTitleCase("ADDRESS"), "Address");
  EXPECT_EQ(toTitleCase("PRODUCT_MANUFACTURER"), "ProductManufacturer");
  EXPECT_EQ(toTitleCase("PRODUCT_SERIAL_NUMBER"), "ProductSerialNumber");
  EXPECT_EQ(toTitleCase("foo_bar_baz"), "FooBarBaz");
  EXPECT_EQ(toTitleCase(""), "");
}

// Tests handleIpmiFruMemberGet with dynamic ObjectMapper service discovery:
// 1. Registers a mock Mapper GetObject response (kManagedMapperObject) mapping
//    the FRU path to its owning service ("xyz.openbmc_project.FruDevice").
// 2. Registers mock D-Bus properties (kManagedPropertyMap) on that service.
// 3. Verifies that handleIpmiFruMemberGet queries the discovered service and
//    populates the Redfish response correctly.
TEST_F(SnapshotFixture, handleIpmiFruMemberGet) {
  std::string fruId = "TestFru1";
  KeyType objKey(ManagedType::kManagedMapperObject,
                 "/xyz/openbmc_project/FruDevice/" + fruId,
                 std::vector<std::string>{"xyz.openbmc_project.FruDevice"});
  dbus::utility::MapperGetObject objVal = {
      {"xyz.openbmc_project.FruDevice", {"xyz.openbmc_project.FruDevice"}}};
  ASSERT_TRUE(
      dynamic_cast<managedStore::MockSerializedManagedObjectStore*>(
          managedStore::GetManagedObjectStore())
          ->upsertMockObjectIntoManagedStore(
              objKey,
              managedStore::MockManagedStoreTest::CreateValueType(objVal))
          .ok());

  KeyType key(ManagedType::kManagedPropertyMap, "xyz.openbmc_project.FruDevice",
              "/xyz/openbmc_project/FruDevice/" + fruId,
              "xyz.openbmc_project.FruDevice");

  DBusPropertiesMap props = {
      {std::make_pair("BUS", DbusVariantType(static_cast<uint32_t>(1)))},
      {std::make_pair("ADDRESS", DbusVariantType(static_cast<uint32_t>(80)))},
      {std::make_pair("BOARD_PRODUCT_NAME", DbusVariantType("BoardName"))}};

  ASSERT_TRUE(
      dynamic_cast<managedStore::MockSerializedManagedObjectStore*>(
          managedStore::GetManagedObjectStore())
          ->upsertMockObjectIntoManagedStore(
              key, managedStore::MockManagedStoreTest::CreateValueType(props))
          .ok());

  handleIpmiFruMemberGet(app_, CreateRequest(), share_async_resp_, fruId);

  RunIoUntilDone();

  nlohmann::json& json = share_async_resp_->res.jsonValue;
  EXPECT_EQ(json, nlohmann::json::parse(R"({
    "@odata.id": "/redfish/v1/Managers/bmc/Oem/Google/FruDevice/IpmiFrus/TestFru1",
    "@odata.type": "#GoogleFruDevice.v1_0_0.IpmiFru",
    "Id": "TestFru1",
    "Name": "Google IPMI FRU",
    "Bus": 1,
    "Address": 80,
    "BoardProductName": "BoardName"
  })"));
  EXPECT_EQ(share_async_resp_->res.result(), boost::beast::http::status::ok);
}

// Tests handleIpmiFruMemberGet when the requested FRU ID does not exist in
// the ObjectMapper, verifying that HTTP 404 (ResourceNotFound) is returned.
TEST_F(SnapshotFixture, handleIpmiFruMemberGetNotFound) {
  handleIpmiFruMemberGet(app_, CreateRequest(), share_async_resp_,
                         "NonExistentFru");

  RunIoUntilDone();

  EXPECT_EQ(share_async_resp_->res.result(),
            boost::beast::http::status::not_found);
}

// Tests end-to-end HTTP request dispatch through Crow router to both IpmiFrus
// and RawEeproms member endpoints:
// 1. Verifies that the Crow router dispatches GET requests for /IpmiFrus/<id>
//    and /RawEeproms/<id> (without trailing slashes) correctly.
// 2. Verifies dynamic ObjectMapper resolution (kManagedMapperObject) and
//    properties population for IpmiFrus.
// 3. Verifies dynamic ObjectMapper resolution and GetRawFru D-Bus method call
//    mock invocation for RawEeproms.
TEST_F(SnapshotFixture, requestRoutesFruDevicesRouteMatching) {
  requestRoutesFruDevices(app_);
  app_.validate();

  std::string fruId = "TestFru1";
  KeyType fruObjKey(ManagedType::kManagedMapperObject,
                    "/xyz/openbmc_project/FruDevice/" + fruId,
                    std::vector<std::string>{"xyz.openbmc_project.FruDevice"});
  dbus::utility::MapperGetObject fruObjVal = {
      {"xyz.openbmc_project.FruDevice", {"xyz.openbmc_project.FruDevice"}}};
  ASSERT_TRUE(
      dynamic_cast<managedStore::MockSerializedManagedObjectStore*>(
          managedStore::GetManagedObjectStore())
          ->upsertMockObjectIntoManagedStore(
              fruObjKey,
              managedStore::MockManagedStoreTest::CreateValueType(fruObjVal))
          .ok());

  KeyType key(ManagedType::kManagedPropertyMap, "xyz.openbmc_project.FruDevice",
              "/xyz/openbmc_project/FruDevice/" + fruId,
              "xyz.openbmc_project.FruDevice");

  DBusPropertiesMap props = {
      {std::make_pair("BUS", DbusVariantType(static_cast<uint32_t>(1)))},
      {std::make_pair("ADDRESS", DbusVariantType(static_cast<uint32_t>(80)))},
      {std::make_pair("BOARD_PRODUCT_NAME", DbusVariantType("BoardName"))}};

  ASSERT_TRUE(
      dynamic_cast<managedStore::MockSerializedManagedObjectStore*>(
          managedStore::GetManagedObjectStore())
          ->upsertMockObjectIntoManagedStore(
              key, managedStore::MockManagedStoreTest::CreateValueType(props))
          .ok());

  boost::beast::http::request<boost::beast::http::string_body> reqIn{
      boost::beast::http::verb::get,
      "/redfish/v1/Managers/bmc/Oem/Google/FruDevice/IpmiFrus/TestFru1", 11};
  std::error_code ec;
  crow::Request req(reqIn, ec);

  auto async_resp = std::make_shared<bmcweb::AsyncResp>();
  app_.handle(req, async_resp);
  RunIoUntilDone();

  EXPECT_EQ(async_resp->res.result(), boost::beast::http::status::ok);
  EXPECT_EQ(async_resp->res.jsonValue["@odata.id"],
            "/redfish/v1/Managers/bmc/Oem/Google/FruDevice/IpmiFrus/TestFru1");
  EXPECT_EQ(async_resp->res.jsonValue["Id"], "TestFru1");

  // Verify RawEeproms member route with dynamic ObjectMapper resolution
  std::string rawId = "Eeprom1";
  KeyType rawObjKey(
      ManagedType::kManagedMapperObject,
      "/xyz/openbmc_project/FruDevice/" + rawId,
      std::vector<std::string>{
          "xyz.openbmc_project.Inventory.Item.I2CDevice"});
  dbus::utility::MapperGetObject rawObjVal = {
      {"xyz.openbmc_project.FruDevice",
       {"xyz.openbmc_project.Inventory.Item.I2CDevice"}}};
  ASSERT_TRUE(
      dynamic_cast<managedStore::MockSerializedManagedObjectStore*>(
          managedStore::GetManagedObjectStore())
          ->upsertMockObjectIntoManagedStore(
              rawObjKey,
              managedStore::MockManagedStoreTest::CreateValueType(rawObjVal))
          .ok());

  KeyType rawKey(ManagedType::kManagedPropertyMap,
                 "xyz.openbmc_project.FruDevice",
                 "/xyz/openbmc_project/FruDevice/" + rawId,
                 "xyz.openbmc_project.Inventory.Item.I2CDevice");
  DBusPropertiesMap rawProps = {
      {std::make_pair("Bus", DbusVariantType(static_cast<uint32_t>(2)))},
      {std::make_pair("Address", DbusVariantType(static_cast<uint32_t>(81)))},
  };
  ASSERT_TRUE(
      dynamic_cast<managedStore::MockSerializedManagedObjectStore*>(
          managedStore::GetManagedObjectStore())
          ->upsertMockObjectIntoManagedStore(
              rawKey,
              managedStore::MockManagedStoreTest::CreateValueType(rawProps))
          .ok());

  EXPECT_CALL(
      *dynamic_cast<managedStore::MockSerializedManagedObjectStore*>(
          managedStore::GetManagedObjectStore()),
      PostDbusCallToIoContextThreadSafe(
          testing::_,
          testing::An<
              absl::AnyInvocable<void(const boost::system::error_code&,
                                      const std::vector<uint8_t>&)>&&>(),
          "xyz.openbmc_project.FruDevice", "/xyz/openbmc_project/FruDevice",
          "xyz.openbmc_project.FruDeviceManager", "GetRawFru",
          testing::Eq(static_cast<uint16_t>(2)),
          testing::Eq(static_cast<uint8_t>(81))))
      .WillOnce(
          managedStore::
              SimulateSuccessfulAsyncPostDbusCallThreadSafeWithValueAction<
                  std::vector<uint8_t>>::
                  SimulateSuccessfulAsyncPostDbusCallWithValue(
                      std::make_shared<std::vector<uint8_t>>(
                          std::vector<uint8_t>{0x01, 0x02, 0x03})));

  boost::beast::http::request<boost::beast::http::string_body> rawReqIn{
      boost::beast::http::verb::get,
      "/redfish/v1/Managers/bmc/Oem/Google/FruDevice/RawEeproms/Eeprom1", 11};
  crow::Request rawReq(rawReqIn, ec);
  auto raw_async_resp = std::make_shared<bmcweb::AsyncResp>();
  app_.handle(rawReq, raw_async_resp);
  RunIoUntilDone();

  EXPECT_EQ(raw_async_resp->res.result(), boost::beast::http::status::ok);
  EXPECT_EQ(raw_async_resp->res.jsonValue["@odata.id"],
            "/redfish/v1/Managers/bmc/Oem/Google/FruDevice/RawEeproms/Eeprom1");
  EXPECT_EQ(raw_async_resp->res.jsonValue["Id"], "Eeprom1");
}

// Tests handleRawEepromMemberGet with dynamic ObjectMapper service discovery:
// 1. Registers mock Mapper GetObject mapping (kManagedMapperObject) for I2CDevice.
// 2. Registers Bus/Address properties on the discovered service.
// 3. Expects GetRawFru D-Bus call to be issued to the discovered service.
TEST_F(SnapshotFixture, handleRawEepromMemberGet) {
  std::string rawId = "Eeprom1";
  KeyType rawObjKey(
      ManagedType::kManagedMapperObject,
      "/xyz/openbmc_project/FruDevice/" + rawId,
      std::vector<std::string>{
          "xyz.openbmc_project.Inventory.Item.I2CDevice"});
  dbus::utility::MapperGetObject rawObjVal = {
      {"xyz.openbmc_project.FruDevice",
       {"xyz.openbmc_project.Inventory.Item.I2CDevice"}}};
  ASSERT_TRUE(
      dynamic_cast<managedStore::MockSerializedManagedObjectStore*>(
          managedStore::GetManagedObjectStore())
          ->upsertMockObjectIntoManagedStore(
              rawObjKey,
              managedStore::MockManagedStoreTest::CreateValueType(rawObjVal))
          .ok());

  KeyType key(ManagedType::kManagedPropertyMap, "xyz.openbmc_project.FruDevice",
              "/xyz/openbmc_project/FruDevice/" + rawId,
              "xyz.openbmc_project.Inventory.Item.I2CDevice");

  DBusPropertiesMap props = {
      {std::make_pair("Bus", DbusVariantType(static_cast<uint32_t>(2)))},
      {std::make_pair("Address", DbusVariantType(static_cast<uint32_t>(81)))},
  };

  ASSERT_TRUE(
      dynamic_cast<managedStore::MockSerializedManagedObjectStore*>(
          managedStore::GetManagedObjectStore())
          ->upsertMockObjectIntoManagedStore(
              key, managedStore::MockManagedStoreTest::CreateValueType(props))
          .ok());

  EXPECT_CALL(
      *dynamic_cast<managedStore::MockSerializedManagedObjectStore*>(
          managedStore::GetManagedObjectStore()),
      PostDbusCallToIoContextThreadSafe(
          testing::_,
          testing::An<
              absl::AnyInvocable<void(const boost::system::error_code&,
                                      const std::vector<uint8_t>&)>&&>(),
          "xyz.openbmc_project.FruDevice", "/xyz/openbmc_project/FruDevice",
          "xyz.openbmc_project.FruDeviceManager", "GetRawFru",
          testing::Eq(static_cast<uint16_t>(2)),
          testing::Eq(static_cast<uint8_t>(81))))
      .WillOnce(
          managedStore::
              SimulateSuccessfulAsyncPostDbusCallThreadSafeWithValueAction<
                  std::vector<uint8_t>>::
                  SimulateSuccessfulAsyncPostDbusCallWithValue(
                      std::make_shared<std::vector<uint8_t>>(
                          std::vector<uint8_t>{1, 2, 3})));

  handleRawEepromMemberGet(app_, CreateRequest(), share_async_resp_, rawId);

  RunIoUntilDone();

  nlohmann::json& json = share_async_resp_->res.jsonValue;
  EXPECT_EQ(json, nlohmann::json::parse(R"({
    "@odata.id": "/redfish/v1/Managers/bmc/Oem/Google/FruDevice/RawEeproms/Eeprom1",
    "@odata.type": "#GoogleFruDevice.v1_0_0.RawEeprom",
    "Id": "Eeprom1",
    "Name": "Google Raw EEPROM",
    "Bus": 2,
    "Address": 81,
    "Status": {
      "State": "Enabled"
    },
    "RawData": [1, 2, 3],
    "HexdumpFormattedRawData": "0000:  01 02 03                                          | ... |\n"
  })"));
  EXPECT_EQ(share_async_resp_->res.result(), boost::beast::http::status::ok);
}

// Tests handleRawEepromMemberGet on 64-bit platforms (e.g., aarch64),
// where FruDevice registers Bus and Address properties as uint64_t (size_t)
// rather than uint32_t.
TEST_F(SnapshotFixture, handleRawEepromMemberGetUint64) {
  std::string rawId = "Eeprom1";
  KeyType rawObjKey(
      ManagedType::kManagedMapperObject,
      "/xyz/openbmc_project/FruDevice/" + rawId,
      std::vector<std::string>{
          "xyz.openbmc_project.Inventory.Item.I2CDevice"});
  dbus::utility::MapperGetObject rawObjVal = {
      {"xyz.openbmc_project.FruDevice",
       {"xyz.openbmc_project.Inventory.Item.I2CDevice"}}};
  ASSERT_TRUE(
      dynamic_cast<managedStore::MockSerializedManagedObjectStore*>(
          managedStore::GetManagedObjectStore())
          ->upsertMockObjectIntoManagedStore(
              rawObjKey,
              managedStore::MockManagedStoreTest::CreateValueType(rawObjVal))
          .ok());

  KeyType key(ManagedType::kManagedPropertyMap, "xyz.openbmc_project.FruDevice",
              "/xyz/openbmc_project/FruDevice/" + rawId,
              "xyz.openbmc_project.Inventory.Item.I2CDevice");

  DBusPropertiesMap props = {
      {std::make_pair("Bus", DbusVariantType(static_cast<uint64_t>(2)))},
      {std::make_pair("Address", DbusVariantType(static_cast<uint64_t>(81)))},
  };

  ASSERT_TRUE(
      dynamic_cast<managedStore::MockSerializedManagedObjectStore*>(
          managedStore::GetManagedObjectStore())
          ->upsertMockObjectIntoManagedStore(
              key, managedStore::MockManagedStoreTest::CreateValueType(props))
          .ok());

  EXPECT_CALL(
      *dynamic_cast<managedStore::MockSerializedManagedObjectStore*>(
          managedStore::GetManagedObjectStore()),
      PostDbusCallToIoContextThreadSafe(
          testing::_,
          testing::An<
              absl::AnyInvocable<void(const boost::system::error_code&,
                                      const std::vector<uint8_t>&)>&&>(),
          "xyz.openbmc_project.FruDevice", "/xyz/openbmc_project/FruDevice",
          "xyz.openbmc_project.FruDeviceManager", "GetRawFru",
          testing::Eq(static_cast<uint16_t>(2)),
          testing::Eq(static_cast<uint8_t>(81))))
      .WillOnce(
          managedStore::
              SimulateSuccessfulAsyncPostDbusCallThreadSafeWithValueAction<
                  std::vector<uint8_t>>::
                  SimulateSuccessfulAsyncPostDbusCallWithValue(
                      std::make_shared<std::vector<uint8_t>>(
                          std::vector<uint8_t>{1, 2, 3})));

  handleRawEepromMemberGet(app_, CreateRequest(), share_async_resp_, rawId);

  RunIoUntilDone();

  nlohmann::json& json = share_async_resp_->res.jsonValue;
  EXPECT_EQ(json, nlohmann::json::parse(R"({
    "@odata.id": "/redfish/v1/Managers/bmc/Oem/Google/FruDevice/RawEeproms/Eeprom1",
    "@odata.type": "#GoogleFruDevice.v1_0_0.RawEeprom",
    "Id": "Eeprom1",
    "Name": "Google Raw EEPROM",
    "Bus": 2,
    "Address": 81,
    "Status": {
      "State": "Enabled"
    },
    "RawData": [1, 2, 3],
    "HexdumpFormattedRawData": "0000:  01 02 03                                          | ... |\n"
  })"));
  EXPECT_EQ(share_async_resp_->res.result(), boost::beast::http::status::ok);
}

TEST_F(SnapshotFixture, handleRawEepromMemberGetZeroLength) {
  std::string rawId = "Eeprom1";
  KeyType key(ManagedType::kManagedPropertyMap, "xyz.openbmc_project.FruDevice",
              "/xyz/openbmc_project/FruDevice/" + rawId,
              "xyz.openbmc_project.Inventory.Item.I2CDevice");

  DBusPropertiesMap props = {
      {std::make_pair("Bus", DbusVariantType(static_cast<uint32_t>(2)))},
      {std::make_pair("Address", DbusVariantType(static_cast<uint32_t>(81)))},
  };

  ASSERT_TRUE(
      dynamic_cast<managedStore::MockSerializedManagedObjectStore*>(
          managedStore::GetManagedObjectStore())
          ->upsertMockObjectIntoManagedStore(
              key, managedStore::MockManagedStoreTest::CreateValueType(props))
          .ok());

  EXPECT_CALL(
      *dynamic_cast<managedStore::MockSerializedManagedObjectStore*>(
          managedStore::GetManagedObjectStore()),
      PostDbusCallToIoContextThreadSafe(
          testing::_,
          testing::An<
              absl::AnyInvocable<void(const boost::system::error_code&,
                                      const std::vector<uint8_t>&)>&&>(),
          "xyz.openbmc_project.FruDevice", "/xyz/openbmc_project/FruDevice",
          "xyz.openbmc_project.FruDeviceManager", "GetRawFru",
          testing::Eq(static_cast<uint16_t>(2)),
          testing::Eq(static_cast<uint8_t>(81))))
      .WillOnce(
          managedStore::
              SimulateSuccessfulAsyncPostDbusCallThreadSafeWithValueAction<
                  std::vector<uint8_t>>::
                  SimulateSuccessfulAsyncPostDbusCallWithValue(
                      std::make_shared<std::vector<uint8_t>>(
                          std::vector<uint8_t>{})));

  handleRawEepromMemberGet(app_, CreateRequest(), share_async_resp_, rawId);

  RunIoUntilDone();

  nlohmann::json& json = share_async_resp_->res.jsonValue;
  EXPECT_EQ(json["Status"]["State"], "Enabled");
  EXPECT_EQ(json["RawData"], std::vector<uint8_t>{});
  EXPECT_EQ(json["HexdumpFormattedRawData"], "");
  EXPECT_EQ(share_async_resp_->res.result(), boost::beast::http::status::ok);
}

TEST_F(SnapshotFixture, handleRawEepromMemberGetMultipleLines) {
  std::string rawId = "Eeprom1";
  KeyType key(ManagedType::kManagedPropertyMap, "xyz.openbmc_project.FruDevice",
              "/xyz/openbmc_project/FruDevice/" + rawId,
              "xyz.openbmc_project.Inventory.Item.I2CDevice");

  DBusPropertiesMap props = {
      {std::make_pair("Bus", DbusVariantType(static_cast<uint32_t>(2)))},
      {std::make_pair("Address", DbusVariantType(static_cast<uint32_t>(81)))},
  };

  ASSERT_TRUE(
      dynamic_cast<managedStore::MockSerializedManagedObjectStore*>(
          managedStore::GetManagedObjectStore())
          ->upsertMockObjectIntoManagedStore(
              key, managedStore::MockManagedStoreTest::CreateValueType(props))
          .ok());

  std::vector<uint8_t> rawData;
  for (int i = 0; i < 20; ++i) {
    rawData.push_back(static_cast<uint8_t>('A' + i));
  }

  EXPECT_CALL(
      *dynamic_cast<managedStore::MockSerializedManagedObjectStore*>(
          managedStore::GetManagedObjectStore()),
      PostDbusCallToIoContextThreadSafe(
          testing::_,
          testing::An<
              absl::AnyInvocable<void(const boost::system::error_code&,
                                      const std::vector<uint8_t>&)>&&>(),
          "xyz.openbmc_project.FruDevice", "/xyz/openbmc_project/FruDevice",
          "xyz.openbmc_project.FruDeviceManager", "GetRawFru",
          testing::Eq(static_cast<uint16_t>(2)),
          testing::Eq(static_cast<uint8_t>(81))))
      .WillOnce(
          managedStore::
              SimulateSuccessfulAsyncPostDbusCallThreadSafeWithValueAction<
                  std::vector<uint8_t>>::
                  SimulateSuccessfulAsyncPostDbusCallWithValue(
                      std::make_shared<std::vector<uint8_t>>(rawData)));

  handleRawEepromMemberGet(app_, CreateRequest(), share_async_resp_, rawId);

  RunIoUntilDone();

  nlohmann::json& json = share_async_resp_->res.jsonValue;
  EXPECT_EQ(json["Status"]["State"], "Enabled");
  EXPECT_EQ(json["RawData"], rawData);

  std::string expectedHexdump =
      "0000:  41 42 43 44 45 46 47 48  49 4A 4B 4C 4D 4E 4F 50  | "
      "ABCDEFGHIJKLMNOP |\n"
      "0010:  51 52 53 54                                       | QRST |\n";
  EXPECT_EQ(json["HexdumpFormattedRawData"], expectedHexdump);
  EXPECT_EQ(share_async_resp_->res.result(), boost::beast::http::status::ok);
}

TEST_F(SnapshotFixture, handleRawEepromMemberGetNotPopulated) {
  std::string rawId = "Eeprom1";
  KeyType key(ManagedType::kManagedPropertyMap, "xyz.openbmc_project.FruDevice",
              "/xyz/openbmc_project/FruDevice/" + rawId,
              "xyz.openbmc_project.Inventory.Item.I2CDevice");

  DBusPropertiesMap props = {
      {std::make_pair("Bus", DbusVariantType(static_cast<uint32_t>(2)))},
      {std::make_pair("Address", DbusVariantType(static_cast<uint32_t>(81)))},
  };

  ASSERT_TRUE(
      dynamic_cast<managedStore::MockSerializedManagedObjectStore*>(
          managedStore::GetManagedObjectStore())
          ->upsertMockObjectIntoManagedStore(
              key, managedStore::MockManagedStoreTest::CreateValueType(props))
          .ok());

  EXPECT_CALL(
      *dynamic_cast<managedStore::MockSerializedManagedObjectStore*>(
          managedStore::GetManagedObjectStore()),
      PostDbusCallToIoContextThreadSafe(
          testing::_,
          testing::An<
              absl::AnyInvocable<void(const boost::system::error_code&,
                                      const std::vector<uint8_t>&)>&&>(),
          "xyz.openbmc_project.FruDevice", "/xyz/openbmc_project/FruDevice",
          "xyz.openbmc_project.FruDeviceManager", "GetRawFru",
          testing::Eq(static_cast<uint16_t>(2)),
          testing::Eq(static_cast<uint8_t>(81))))
      .WillOnce(
          managedStore::
              SimulateFailedAsyncPostDbusCallThreadSafeWithEmptyValueAction::
                  SimulateFailedAsyncPostDbusCallWithEmptyValue(
                      boost::system::errc::make_error_code(
                          boost::system::errc::invalid_argument)));

  handleRawEepromMemberGet(app_, CreateRequest(), share_async_resp_, rawId);

  RunIoUntilDone();

  nlohmann::json& json = share_async_resp_->res.jsonValue;
  EXPECT_EQ(json, nlohmann::json::parse(R"({
    "@odata.id": "/redfish/v1/Managers/bmc/Oem/Google/FruDevice/RawEeproms/Eeprom1",
    "@odata.type": "#GoogleFruDevice.v1_0_0.RawEeprom",
    "Id": "Eeprom1",
    "Name": "Google Raw EEPROM",
    "Bus": 2,
    "Address": 81,
    "Status": {
      "State": "Disabled"
    }
  })"));
  EXPECT_EQ(share_async_resp_->res.result(), boost::beast::http::status::ok);
}

TEST_F(SnapshotFixture, handleRawEepromMemberGetInternalError) {
  std::string rawId = "Eeprom1";
  KeyType key(ManagedType::kManagedPropertyMap, "xyz.openbmc_project.FruDevice",
              "/xyz/openbmc_project/FruDevice/" + rawId,
              "xyz.openbmc_project.Inventory.Item.I2CDevice");

  DBusPropertiesMap props = {
      {std::make_pair("Bus", DbusVariantType(static_cast<uint32_t>(2)))},
      {std::make_pair("Address", DbusVariantType(static_cast<uint32_t>(81)))},
  };

  ASSERT_TRUE(
      dynamic_cast<managedStore::MockSerializedManagedObjectStore*>(
          managedStore::GetManagedObjectStore())
          ->upsertMockObjectIntoManagedStore(
              key, managedStore::MockManagedStoreTest::CreateValueType(props))
          .ok());

  EXPECT_CALL(
      *dynamic_cast<managedStore::MockSerializedManagedObjectStore*>(
          managedStore::GetManagedObjectStore()),
      PostDbusCallToIoContextThreadSafe(
          testing::_,
          testing::An<
              absl::AnyInvocable<void(const boost::system::error_code&,
                                      const std::vector<uint8_t>&)>&&>(),
          "xyz.openbmc_project.FruDevice", "/xyz/openbmc_project/FruDevice",
          "xyz.openbmc_project.FruDeviceManager", "GetRawFru",
          testing::Eq(static_cast<uint16_t>(2)),
          testing::Eq(static_cast<uint8_t>(81))))
      .WillOnce(
          managedStore::
              SimulateFailedAsyncPostDbusCallThreadSafeWithEmptyValueAction::
                  SimulateFailedAsyncPostDbusCallWithEmptyValue(
                      boost::system::errc::make_error_code(
                          boost::system::errc::io_error)));

  handleRawEepromMemberGet(app_, CreateRequest(), share_async_resp_, rawId);

  RunIoUntilDone();

  EXPECT_EQ(share_async_resp_->res.result(),
            boost::beast::http::status::internal_server_error);
}

TEST_F(SnapshotFixture, handleRawEepromMemberGetNotFound) {
  handleRawEepromMemberGet(app_, CreateRequest(), share_async_resp_,
                           "NonExistentEeprom");

  RunIoUntilDone();

  EXPECT_EQ(share_async_resp_->res.result(),
            boost::beast::http::status::not_found);
}

TEST_F(SnapshotFixture, handleIpmiFruCollectionGetInvalidOdataVersion) {
  boost::beast::http::request<boost::beast::http::string_body> reqIn;
  reqIn.set("OData-Version", "3.0");
  std::error_code ec;
  crow::Request req(reqIn, ec);
  handleIpmiFruCollectionGet(app_, req, share_async_resp_);
  RunIoUntilDone();
  EXPECT_EQ(share_async_resp_->res.result(),
            boost::beast::http::status::precondition_failed);
}

TEST_F(SnapshotFixture, handleRawEepromCollectionGetInvalidOdataVersion) {
  boost::beast::http::request<boost::beast::http::string_body> reqIn;
  reqIn.set("OData-Version", "3.0");
  std::error_code ec;
  crow::Request req(reqIn, ec);
  handleRawEepromCollectionGet(app_, req, share_async_resp_);
  RunIoUntilDone();
  EXPECT_EQ(share_async_resp_->res.result(),
            boost::beast::http::status::precondition_failed);
}

TEST_F(SnapshotFixture, handleIpmiFruMemberGetInvalidId) {
  std::string fruId = "Test-Fru";
  handleIpmiFruMemberGet(app_, CreateRequest(), share_async_resp_, fruId);
  RunIoUntilDone();
  EXPECT_EQ(share_async_resp_->res.result(),
            boost::beast::http::status::not_found);
}

TEST_F(SnapshotFixture, handleRawEepromMemberGetInvalidId) {
  std::string rawId = "Eeprom.1";
  handleRawEepromMemberGet(app_, CreateRequest(), share_async_resp_, rawId);
  RunIoUntilDone();
  EXPECT_EQ(share_async_resp_->res.result(),
            boost::beast::http::status::not_found);
}

TEST_F(SnapshotFixture, asyncPopulatePidZoneChassisValid) {
  const std::string connection = "xyz.openbmc_project.EntityManager";
  const std::string path = "/xyz/openbmc_project/inventory";
  const std::string zoneName = "Zone_0";
  const std::string chassisName = "TestChassis";

  // Mock ManagedObjectType for asyncPopulatePid
  dbus::utility::ManagedObjectType managedObj = {
      {sdbusplus::message::object_path(
           "/xyz/openbmc_project/inventory/system/chassis/" + chassisName +
           "/" + zoneName),
       {{"xyz.openbmc_project.Configuration.Pid.Zone",
         {{"Name", DbusVariantType(zoneName)},
          {"Class", DbusVariantType("temp")},
          {"ZoneIndex", DbusVariantType(0.0)},
          {"MinThermalOutput", DbusVariantType(3000.0)}}}}}};

  KeyType objKey(ManagedType::kManagedObject, connection, path);
  ASSERT_TRUE(dynamic_cast<managedStore::MockSerializedManagedObjectStore*>(
                  managedStore::GetManagedObjectStore())
                  ->upsertMockObjectIntoManagedStore(
                      objKey, managedStore::MockManagedStoreTest::CreateValueType(
                                  managedObj))
                  .ok());

  // Mock chassis subtree paths containing the matching chassis
  std::vector<std::string> chassisPaths = {
      "/xyz/openbmc_project/inventory/system/chassis/" + chassisName,
  };
  KeyType chassisSubtreeKey(
      ManagedType::kManagedSubtreePaths, "/xyz/openbmc_project/inventory", 0,
      {"xyz.openbmc_project.Inventory.Item.Board",
       "xyz.openbmc_project.Inventory.Item.Chassis"});
  ASSERT_TRUE(dynamic_cast<managedStore::MockSerializedManagedObjectStore*>(
                  managedStore::GetManagedObjectStore())
                  ->upsertMockObjectIntoManagedStore(
                      chassisSubtreeKey,
                      managedStore::MockManagedStoreTest::CreateValueType(
                          chassisPaths))
                  .ok());

  asyncPopulatePid(connection, path, "", {}, share_async_resp_);
  RunIoUntilDone();

  nlohmann::json& json = share_async_resp_->res.jsonValue;
  EXPECT_EQ(
      json["Oem"]["OpenBmc"]["Fan"]["FanZones"][zoneName]["Chassis"]["@odata.id"],
      "/redfish/v1/Chassis/" + chassisName);
}

TEST_F(SnapshotFixture, asyncPopulatePidZoneChassisInvalid) {
  const std::string connection = "xyz.openbmc_project.EntityManager";
  const std::string path = "/xyz/openbmc_project/inventory";
  const std::string zoneName = "Zone_0";
  const std::string chassisName = "InvalidChassis";

  // Mock ManagedObjectType with an invalid chassis name in the path
  dbus::utility::ManagedObjectType managedObj = {
      {sdbusplus::message::object_path(
           "/xyz/openbmc_project/inventory/system/chassis/" + chassisName +
           "/" + zoneName),
       {{"xyz.openbmc_project.Configuration.Pid.Zone",
         {{"Name", DbusVariantType(zoneName)},
          {"Class", DbusVariantType("temp")},
          {"ZoneIndex", DbusVariantType(0.0)},
          {"MinThermalOutput", DbusVariantType(3000.0)}}}}}};

  KeyType objKey(ManagedType::kManagedObject, connection, path);
  ASSERT_TRUE(dynamic_cast<managedStore::MockSerializedManagedObjectStore*>(
                  managedStore::GetManagedObjectStore())
                  ->upsertMockObjectIntoManagedStore(
                      objKey, managedStore::MockManagedStoreTest::CreateValueType(
                                  managedObj))
                  .ok());

  // Mock chassis subtree paths containing only OtherChassis (not InvalidChassis)
  std::vector<std::string> chassisPaths = {
      "/xyz/openbmc_project/inventory/system/chassis/OtherChassis",
  };
  KeyType chassisSubtreeKey(
      ManagedType::kManagedSubtreePaths, "/xyz/openbmc_project/inventory", 0,
      {"xyz.openbmc_project.Inventory.Item.Board",
       "xyz.openbmc_project.Inventory.Item.Chassis"});
  ASSERT_TRUE(dynamic_cast<managedStore::MockSerializedManagedObjectStore*>(
                  managedStore::GetManagedObjectStore())
                  ->upsertMockObjectIntoManagedStore(
                      chassisSubtreeKey,
                      managedStore::MockManagedStoreTest::CreateValueType(
                          chassisPaths))
                  .ok());

  asyncPopulatePid(connection, path, "", {}, share_async_resp_);
  RunIoUntilDone();

  nlohmann::json& json = share_async_resp_->res.jsonValue;
  // When chassis is invalid, Chassis property should not be reported
  EXPECT_FALSE(
      json["Oem"]["OpenBmc"]["Fan"]["FanZones"][zoneName].contains("Chassis"));
}

}  // namespace
}  // namespace redfish
