/*
 *
 *    Copyright (c) 2024 Project CHIP Authors
 *    All rights reserved.
 *
 *    Licensed under the Apache License, Version 2.0 (the "License");
 *    you may not use this file except in compliance with the License.
 *    You may obtain a copy of the License at
 *
 *        http://www.apache.org/licenses/LICENSE-2.0
 *
 *    Unless required by applicable law or agreed to in writing, software
 *    distributed under the License is distributed on an "AS IS" BASIS,
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *    See the License for the specific language governing permissions and
 *    limitations under the License.
 */
#include <app-common/zap-generated/cluster-objects.h>
#include <app/clusters/closure-dimension-server/closure-dimension-cluster-logic.h>
#include <app/clusters/closure-dimension-server/closure-dimension-cluster-objects.h>
#include <app/clusters/closure-dimension-server/closure-dimension-delegate.h>
#include <app/clusters/closure-dimension-server/closure-dimension-matter-context.h>
#include <lib/support/CHIPMem.h>
#include <lib/support/UnitTestUtils.h>
#include <platform/CHIPDeviceLayer.h>
#include <pw_unit_test/framework.h>
#include <system/SystemClock.h>
#include <system/SystemTimer.h>
#include <vector>

using namespace chip::app::Clusters::ClosureDimension;

namespace chip {
namespace app {
namespace Clusters {
namespace ClosureDimension {

class TestDelegate : public DelegateBase
{
public:
    TestDelegate() {}

    Protocols::InteractionModel::Status HandleSetTarget(const Optional<Percent100ths> & position, const Optional<bool> & latch,
                                                        const Optional<Globals::ThreeLevelAutoEnum> & speed)
    {
        return Protocols::InteractionModel::Status::Success;
    }

    Protocols::InteractionModel::Status HandleStep(const StepDirectionEnum & direction, const uint16_t & numberOfSteps,
                                                   const Optional<Globals::ThreeLevelAutoEnum> & speed)
    {
        return Protocols::InteractionModel::Status::Success;
    }

    void SetManualLatching(const bool manualLatch) { isLatchManual = manualLatch; }

private:
    bool isLatchManual = false;
};

class MockMatterContext : public MatterContext
{
public:
    MockMatterContext() : MatterContext(kInvalidEndpointId) {}
    void MarkDirty(AttributeId id) override { mDirtyMarkedList.push_back(id); }
    std::vector<AttributeId> GetDirtyList() { return mDirtyMarkedList; }
    void ClearDirtyList() { mDirtyMarkedList.clear(); }
    ~MockMatterContext() = default;

private:
    // Won't handle double-marking an attribute, so don't do that in tests
    std::vector<AttributeId> mDirtyMarkedList;
};

class TestClosureDimensionClusterLogic : public ::testing::Test
{
public:
    static void SetUpTestSuite() { ASSERT_EQ(Platform::MemoryInit(), CHIP_NO_ERROR); }

    static void TearDownTestSuite() { Platform::MemoryShutdown(); }

    void SetUp() override
    {
        mockDelegate = TestDelegate();
        mockContext  = MockMatterContext();
        conformance  = ClusterConformance();
        logic        = std::make_unique<ClusterLogic>(mockDelegate, mockContext);

        // Add values to attributes need to be set in Init()
        initParams.modulationType       = ModulationTypeEnum::kOpacity;
        initParams.rotationAxis         = RotationAxisEnum::kBottom;
        initParams.translationDirection = TranslationDirectionEnum::kBackward;
    }

    void TearDown() override { logic.reset(); }

    TestDelegate mockDelegate;
    MockMatterContext mockContext;
    ClusterConformance conformance;
    ClusterInitParameters initParams;
    std::unique_ptr<ClusterLogic> logic;
};

bool HasAttributeChanges(std::vector<AttributeId> changes, AttributeId id)
{
    return std::find(changes.begin(), changes.end(), id) != changes.end();
}

//=========================================================================================
// Tests for conformance
//=========================================================================================

/*
    ClusterConformance Valid Function Test Case
*/
TEST_F(TestClosureDimensionClusterLogic, TestConformanceValid)
{

    // Validating if either Positioning or MotionLatching is supported. If neither are enabled, returns false.

    // Neither Positioning or MotionLatching is enabled , return false.
    EXPECT_FALSE(conformance.Valid());

    conformance.FeatureMap().Set(Feature::kPositioning);
    EXPECT_TRUE(conformance.Valid());
    conformance.FeatureMap().ClearAll();

    conformance.FeatureMap().Set(Feature::kMotionLatching);
    EXPECT_TRUE(conformance.Valid());
    conformance.FeatureMap().ClearAll();

    // Validating If Unit, Limitation or speed is enabled, Positioning must be enabled. Return false otherwise.

    // Speed is enabled, Positioning is not enabled. Return false.
    conformance.FeatureMap().Set(Feature::kSpeed);
    EXPECT_FALSE(conformance.Valid());
    conformance.FeatureMap().ClearAll();

    // Limitation is enabled, Positioning is not enabled. Return false.
    conformance.FeatureMap().Set(Feature::kLimitation);
    EXPECT_FALSE(conformance.Valid());
    conformance.FeatureMap().ClearAll();

    // Unit is enabled, Positioning is not enabled. Return false.
    conformance.FeatureMap().Set(Feature::kUnit);
    EXPECT_FALSE(conformance.Valid());
    conformance.FeatureMap().ClearAll();

    // Speed is enabled, Positioning is also enabled. Return true.
    conformance.FeatureMap().Set(Feature::kPositioning).Set(Feature::kSpeed);
    EXPECT_TRUE(conformance.Valid());
    conformance.FeatureMap().ClearAll();

    // Limitation is enabled, Positioning is also enabled. Return true.
    conformance.FeatureMap().Set(Feature::kPositioning).Set(Feature::kLimitation);
    EXPECT_TRUE(conformance.Valid());
    conformance.FeatureMap().ClearAll();

    // Unit is enabled, Positioning is also enabled. Return true.
    conformance.FeatureMap().Set(Feature::kPositioning).Set(Feature::kUnit);
    EXPECT_TRUE(conformance.Valid());
    conformance.FeatureMap().ClearAll();

    // Validating If Translation, Rotation or Modulation is enabled, Positioning must be enabled. Return false otherwise.

    // Translation is enabled, Positioning is not enabled. Return false
    conformance.FeatureMap().Set(Feature::kTranslation);
    EXPECT_FALSE(conformance.Valid());
    conformance.FeatureMap().ClearAll();

    // Rotation is enabled, Positioning is not enabled. Return false
    conformance.FeatureMap().Set(Feature::kRotation);
    EXPECT_FALSE(conformance.Valid());
    conformance.FeatureMap().ClearAll();

    // Modulation is enabled, Positioning is not enabled. Return false
    conformance.FeatureMap().Set(Feature::kModulation);
    EXPECT_FALSE(conformance.Valid());
    conformance.FeatureMap().ClearAll();

    // Translation is enabled, Positioning is enabled. Return true
    conformance.FeatureMap().Set(Feature::kPositioning).Set(Feature::kTranslation);
    EXPECT_TRUE(conformance.Valid());
    conformance.FeatureMap().ClearAll();

    // Rotation is enabled, Positioning is enabled. Return true
    conformance.FeatureMap().Set(Feature::kPositioning).Set(Feature::kRotation);
    EXPECT_TRUE(conformance.Valid());
    conformance.FeatureMap().ClearAll();

    // Modulation is enabled, Positioning is enabled. Return true
    conformance.FeatureMap().Set(Feature::kPositioning).Set(Feature::kModulation);
    EXPECT_TRUE(conformance.Valid());
    conformance.FeatureMap().ClearAll();

    // Validating Only one of Translation, Rotation or Modulation must be enabled. Return false otherwise.

    // If Positioning is enabled, all 3 Translation, Rotation and  Modulation are enabled. Return false
    conformance.FeatureMap()
        .Set(Feature::kPositioning)
        .Set(Feature::kTranslation)
        .Set(Feature::kRotation)
        .Set(Feature::kModulation);
    EXPECT_FALSE(conformance.Valid());
    conformance.FeatureMap().ClearAll();

    // If Positioning is enabled, both Rotation and  Modulation are enabled. Return false
    conformance.FeatureMap().Set(Feature::kPositioning).Set(Feature::kRotation).Set(Feature::kModulation);
    EXPECT_FALSE(conformance.Valid());
    conformance.FeatureMap().ClearAll();

    // If Positioning is enabled, both Translation and Rotation are enabled. Return false
    conformance.FeatureMap().Set(Feature::kPositioning).Set(Feature::kTranslation).Set(Feature::kRotation);
    EXPECT_FALSE(conformance.Valid());
    conformance.FeatureMap().ClearAll();

    // If Positioning is enabled, both Translation and  Modulation are enabled. Return false
    conformance.FeatureMap().Set(Feature::kPositioning).Set(Feature::kTranslation).Set(Feature::kModulation);
    EXPECT_FALSE(conformance.Valid());
    conformance.FeatureMap().ClearAll();
}

// This test ensures the Init function with proper parameters should pass and reintilization should fail.
TEST_F(TestClosureDimensionClusterLogic, TestInit)
{
    conformance.FeatureMap().Set(Feature::kPositioning).Set(Feature::kModulation);

    initParams.modulationType       = ModulationTypeEnum::kOpacity;
    initParams.rotationAxis         = RotationAxisEnum::kBottom;
    initParams.translationDirection = TranslationDirectionEnum::kBackward;

    mockContext.ClearDirtyList();

    EXPECT_EQ(logic->Init(conformance, initParams), CHIP_NO_ERROR);
    EXPECT_TRUE(HasAttributeChanges(mockContext.GetDirtyList(), Attributes::ModulationType::Id));
    EXPECT_FALSE(HasAttributeChanges(mockContext.GetDirtyList(), Attributes::RotationAxis::Id));
    EXPECT_FALSE(HasAttributeChanges(mockContext.GetDirtyList(), Attributes::TranslationDirection::Id));

    ClusterState state = logic->GetState();

    EXPECT_EQ(state.modulationType, ModulationTypeEnum::kOpacity);
    EXPECT_EQ(state.rotationAxis, RotationAxisEnum::kUnknownEnumValue);
    EXPECT_EQ(state.translationDirection, TranslationDirectionEnum::kUnknownEnumValue);

    // ReInit should fail
    EXPECT_EQ(logic->Init(conformance, initParams), CHIP_ERROR_INCORRECT_STATE);
}

// This test ensures the Init function with Invalid conformance should fail.
TEST_F(TestClosureDimensionClusterLogic, TestInvalidConformance)
{
    conformance.FeatureMap();

    mockContext.ClearDirtyList();

    EXPECT_EQ(logic->Init(conformance, initParams), CHIP_ERROR_INVALID_DEVICE_DESCRIPTOR);
    ;
    EXPECT_FALSE(HasAttributeChanges(mockContext.GetDirtyList(), Attributes::ModulationType::Id));
    EXPECT_FALSE(HasAttributeChanges(mockContext.GetDirtyList(), Attributes::RotationAxis::Id));
    EXPECT_FALSE(HasAttributeChanges(mockContext.GetDirtyList(), Attributes::TranslationDirection::Id));

    ClusterState state = logic->GetState();
    EXPECT_EQ(state.modulationType, ModulationTypeEnum::kUnknownEnumValue);
    EXPECT_EQ(state.rotationAxis, RotationAxisEnum::kUnknownEnumValue);
    EXPECT_EQ(state.translationDirection, TranslationDirectionEnum::kUnknownEnumValue);
}

// This test ensures the Init function with Invalid InitParameters should fail.
TEST_F(TestClosureDimensionClusterLogic, TestInvalidInitParameters)
{
    conformance.FeatureMap().Set(Feature::kPositioning).Set(Feature::kModulation);

    initParams.modulationType = ModulationTypeEnum::kUnknownEnumValue;

    mockContext.ClearDirtyList();

    EXPECT_EQ(logic->Init(conformance, initParams), CHIP_ERROR_INVALID_ARGUMENT);
    EXPECT_FALSE(HasAttributeChanges(mockContext.GetDirtyList(), Attributes::ModulationType::Id));
    EXPECT_FALSE(HasAttributeChanges(mockContext.GetDirtyList(), Attributes::RotationAxis::Id));
    EXPECT_FALSE(HasAttributeChanges(mockContext.GetDirtyList(), Attributes::TranslationDirection::Id));

    ClusterState state = logic->GetState();
    EXPECT_EQ(state.modulationType, ModulationTypeEnum::kUnknownEnumValue);
    EXPECT_EQ(state.rotationAxis, RotationAxisEnum::kUnknownEnumValue);
    EXPECT_EQ(state.translationDirection, TranslationDirectionEnum::kUnknownEnumValue);
}

//=========================================================================================
// Tests for Featuremap and Cluster Revision Attribute
//=========================================================================================

// This test ensures the get FeatureMap get the Featuremap set from conformance
TEST_F(TestClosureDimensionClusterLogic, TestFeatureMap)
{
    conformance.FeatureMap().Set(Feature::kPositioning);

    mockContext.ClearDirtyList();

    EXPECT_EQ(logic->Init(conformance, initParams), CHIP_NO_ERROR);
    EXPECT_FALSE(HasAttributeChanges(mockContext.GetDirtyList(), Attributes::ModulationType::Id));
    EXPECT_FALSE(HasAttributeChanges(mockContext.GetDirtyList(), Attributes::RotationAxis::Id));
    EXPECT_FALSE(HasAttributeChanges(mockContext.GetDirtyList(), Attributes::TranslationDirection::Id));

    BitFlags<Feature> featureMap;

    EXPECT_EQ(logic->GetFeatureMap(featureMap), CHIP_NO_ERROR);
    EXPECT_EQ(featureMap, conformance.FeatureMap());
}

// This test ensures the get ClusterRevision get the intended value
TEST_F(TestClosureDimensionClusterLogic, TestClusterRevision)
{
    conformance.FeatureMap().Set(Feature::kPositioning);

    mockContext.ClearDirtyList();

    EXPECT_EQ(logic->Init(conformance, initParams), CHIP_NO_ERROR);
    EXPECT_FALSE(HasAttributeChanges(mockContext.GetDirtyList(), Attributes::ModulationType::Id));
    EXPECT_FALSE(HasAttributeChanges(mockContext.GetDirtyList(), Attributes::RotationAxis::Id));
    EXPECT_FALSE(HasAttributeChanges(mockContext.GetDirtyList(), Attributes::TranslationDirection::Id));

    uint16_t kExpectedClusterRevision = 1u;
    Attributes::ClusterRevision::TypeInfo::Type clusterRevision;

    EXPECT_EQ(logic->GetClusterRevision(clusterRevision), CHIP_NO_ERROR);
    EXPECT_EQ(clusterRevision, kExpectedClusterRevision);
}

//=========================================================================================
// Tests for CurrentState Attribute
//=========================================================================================

// This test ensures that the set/get of CurrentState without Intialisation
// - should return CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE
TEST_F(TestClosureDimensionClusterLogic, TestCurrentStateWithNoIntialisation)
{
    GenericDimensionStateStruct testCurrentStateStruct{ Optional<Percent100ths>(0), Optional<bool>(false),
                                                        Optional<Globals::ThreeLevelAutoEnum>(Globals::ThreeLevelAutoEnum::kAuto) };

    DataModel::Nullable<GenericDimensionStateStruct> testCurrentState(testCurrentStateStruct);
    DataModel::Nullable<GenericDimensionStateStruct> currentState;

    mockContext.ClearDirtyList();
    EXPECT_EQ(logic->GetCurrentState(currentState), CHIP_ERROR_INCORRECT_STATE);
    EXPECT_EQ(logic->SetCurrentState(testCurrentState), CHIP_ERROR_INCORRECT_STATE);
    EXPECT_FALSE(HasAttributeChanges(mockContext.GetDirtyList(), Attributes::CurrentState::Id));
}

// This test ensures that the set of CurrentState without Positioning feature
// - should return CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE if position feild is present
// - should return CHIP_NO_ERROR if position feild is abscent
TEST_F(TestClosureDimensionClusterLogic, TestCurrentStateWithNoPositioningFeature)
{
    GenericDimensionStateStruct testCurrentStateStruct{ Optional<Percent100ths>(0), Optional<bool>(false),
                                                        Optional<Globals::ThreeLevelAutoEnum>(Globals::ThreeLevelAutoEnum::kAuto) };

    DataModel::Nullable<GenericDimensionStateStruct> testCurrentState(testCurrentStateStruct);
    DataModel::Nullable<GenericDimensionStateStruct> currentState;

    conformance.FeatureMap().Set(Feature::kMotionLatching);

    EXPECT_EQ(logic->Init(conformance, initParams), CHIP_NO_ERROR);
    mockContext.ClearDirtyList();

    // Get default value
    EXPECT_EQ(logic->GetCurrentState(currentState), CHIP_NO_ERROR);
    EXPECT_EQ(currentState, DataModel::NullNullable);

    // Set current state will with position field without positioning
    EXPECT_EQ(logic->SetCurrentState(testCurrentState), CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE);
    EXPECT_EQ(logic->GetCurrentState(currentState), CHIP_NO_ERROR);
    EXPECT_EQ(currentState, DataModel::NullNullable);
    EXPECT_FALSE(HasAttributeChanges(mockContext.GetDirtyList(), Attributes::CurrentState::Id));

    // Set currentstate without position
    //  we set speed aslo NULL as speed feature is positioning optional.
    testCurrentStateStruct.Set(NullOptional, Optional<bool>(false), NullOptional);
    testCurrentState.SetNonNull(testCurrentStateStruct);
    EXPECT_EQ(logic->SetCurrentState(testCurrentState), CHIP_NO_ERROR);
    EXPECT_EQ(logic->GetCurrentState(currentState), CHIP_NO_ERROR);
    EXPECT_EQ(currentState, testCurrentState);
    EXPECT_TRUE(HasAttributeChanges(mockContext.GetDirtyList(), Attributes::CurrentState::Id));
}

// This test ensures that the set of CurrentState without MotionLatching feature
// - should return CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE if latch feild is present
// - should return CHIP_NO_ERROR if latch feild is abscent
TEST_F(TestClosureDimensionClusterLogic, TestCurrentStateWithNoMotionLatchingFeature)
{
    GenericDimensionStateStruct testCurrentStateStruct{ Optional<Percent100ths>(0), Optional<bool>(false),
                                                        Optional<Globals::ThreeLevelAutoEnum>(Globals::ThreeLevelAutoEnum::kAuto) };

    DataModel::Nullable<GenericDimensionStateStruct> testCurrentState(testCurrentStateStruct);
    DataModel::Nullable<GenericDimensionStateStruct> currentState;

    conformance.FeatureMap().Set(Feature::kPositioning).Set(Feature::kSpeed);

    EXPECT_EQ(logic->Init(conformance, initParams), CHIP_NO_ERROR);
    mockContext.ClearDirtyList();

    // Get default value
    EXPECT_EQ(logic->GetCurrentState(currentState), CHIP_NO_ERROR);
    EXPECT_EQ(currentState, DataModel::NullNullable);

    // Set current state will with position field without positioning
    EXPECT_EQ(logic->SetCurrentState(testCurrentState), CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE);
    EXPECT_EQ(logic->GetCurrentState(currentState), CHIP_NO_ERROR);
    EXPECT_EQ(currentState, DataModel::NullNullable);
    EXPECT_FALSE(HasAttributeChanges(mockContext.GetDirtyList(), Attributes::CurrentState::Id));

    // Set currentstate without position
    //  we set speed aslo NULL as speed feature is positioning optional.
    testCurrentStateStruct.Set(Optional<Percent100ths>(0), NullOptional,
                               Optional<Globals::ThreeLevelAutoEnum>(Globals::ThreeLevelAutoEnum::kAuto));
    testCurrentState.SetNonNull(testCurrentStateStruct);
    EXPECT_EQ(logic->SetCurrentState(testCurrentState), CHIP_NO_ERROR);
    EXPECT_EQ(logic->GetCurrentState(currentState), CHIP_NO_ERROR);
    EXPECT_EQ(currentState, testCurrentState);
    EXPECT_TRUE(HasAttributeChanges(mockContext.GetDirtyList(), Attributes::CurrentState::Id));
}

// This test ensures that the set of CurrentState without Speed feature
// - should return CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE if speed field is present
// - should return CHIP_NO_ERROR if speed field is abscent
TEST_F(TestClosureDimensionClusterLogic, TestCurrentStateWithNoSpeedFeature)
{
    GenericDimensionStateStruct testCurrentStateStruct{ Optional<Percent100ths>(0), Optional<bool>(false),
                                                        Optional<Globals::ThreeLevelAutoEnum>(Globals::ThreeLevelAutoEnum::kAuto) };

    DataModel::Nullable<GenericDimensionStateStruct> testCurrentState(testCurrentStateStruct);
    DataModel::Nullable<GenericDimensionStateStruct> currentState;

    conformance.FeatureMap().Set(Feature::kPositioning).Set(Feature::kMotionLatching);

    EXPECT_EQ(logic->Init(conformance, initParams), CHIP_NO_ERROR);
    mockContext.ClearDirtyList();

    // Get default value
    EXPECT_EQ(logic->GetCurrentState(currentState), CHIP_NO_ERROR);
    EXPECT_EQ(currentState, DataModel::NullNullable);

    // Set current state will with position field without positioning
    EXPECT_EQ(logic->SetCurrentState(testCurrentState), CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE);
    EXPECT_EQ(logic->GetCurrentState(currentState), CHIP_NO_ERROR);
    EXPECT_EQ(currentState, DataModel::NullNullable);
    EXPECT_FALSE(HasAttributeChanges(mockContext.GetDirtyList(), Attributes::CurrentState::Id));

    // Set currentstate without position
    //  we set speed aslo NULL as speed feature is positioning optional.
    testCurrentStateStruct.Set(Optional<Percent100ths>(0), Optional<bool>(false), NullOptional);
    testCurrentState.SetNonNull(testCurrentStateStruct);
    EXPECT_EQ(logic->SetCurrentState(testCurrentState), CHIP_NO_ERROR);
    EXPECT_EQ(logic->GetCurrentState(currentState), CHIP_NO_ERROR);
    EXPECT_EQ(currentState, testCurrentState);
    EXPECT_TRUE(HasAttributeChanges(mockContext.GetDirtyList(), Attributes::CurrentState::Id));
}

// This test ensures that the Setter and getter for currentstate
// - sets/gets the value properly
// - error for constraints checks
TEST_F(TestClosureDimensionClusterLogic, TestCurrentState)
{
    conformance.FeatureMap().Set(Feature::kPositioning).Set(Feature::kMotionLatching).Set(Feature::kSpeed);

    EXPECT_EQ(logic->Init(conformance, initParams), CHIP_NO_ERROR);
    mockContext.ClearDirtyList();

    GenericDimensionStateStruct testCurrentStateStruct{ Optional<Percent100ths>(0), Optional<bool>(false),
                                                        Optional<Globals::ThreeLevelAutoEnum>(Globals::ThreeLevelAutoEnum::kAuto) };

    DataModel::Nullable<GenericDimensionStateStruct> testCurrentState(testCurrentStateStruct);
    DataModel::Nullable<GenericDimensionStateStruct> currentState;

    EXPECT_EQ(logic->GetCurrentState(currentState), CHIP_NO_ERROR);
    EXPECT_EQ(currentState, DataModel::NullNullable);

    // set Values
    EXPECT_EQ(logic->SetCurrentState(testCurrentState), CHIP_NO_ERROR);
    // Ensure the value is accessible via the API
    EXPECT_EQ(logic->GetCurrentState(currentState), CHIP_NO_ERROR);
    EXPECT_EQ(currentState, testCurrentState);
    EXPECT_TRUE(HasAttributeChanges(mockContext.GetDirtyList(), Attributes::CurrentState::Id));

    mockContext.ClearDirtyList();
    // Change values
    testCurrentStateStruct.Set(Optional<Percent100ths>(10000), Optional<bool>(true),
                               Optional<Globals::ThreeLevelAutoEnum>(Globals::ThreeLevelAutoEnum::kHigh));
    testCurrentState.SetNonNull(testCurrentStateStruct);
    EXPECT_EQ(logic->SetCurrentState(testCurrentState), CHIP_NO_ERROR);
    EXPECT_EQ(logic->GetCurrentState(currentState), CHIP_NO_ERROR);
    EXPECT_EQ(currentState, testCurrentState);
    EXPECT_TRUE(HasAttributeChanges(mockContext.GetDirtyList(), Attributes::CurrentState::Id));

    mockContext.ClearDirtyList();
    // Change to NULL
    testCurrentState.SetNull();
    EXPECT_EQ(logic->SetCurrentState(testCurrentState), CHIP_NO_ERROR);
    EXPECT_EQ(logic->GetCurrentState(currentState), CHIP_NO_ERROR);
    EXPECT_EQ(currentState, DataModel::NullNullable);
    EXPECT_TRUE(HasAttributeChanges(mockContext.GetDirtyList(), Attributes::CurrentState::Id));

    mockContext.ClearDirtyList();
    // Change from NULL
    testCurrentStateStruct.Set(Optional<Percent100ths>(5000), Optional<bool>(false),
                               Optional<Globals::ThreeLevelAutoEnum>(Globals::ThreeLevelAutoEnum::kMedium));
    testCurrentState.SetNonNull(testCurrentStateStruct);
    EXPECT_EQ(logic->SetCurrentState(testCurrentState), CHIP_NO_ERROR);
    EXPECT_EQ(logic->GetCurrentState(currentState), CHIP_NO_ERROR);
    EXPECT_EQ(currentState, testCurrentState);
    EXPECT_TRUE(HasAttributeChanges(mockContext.GetDirtyList(), Attributes::CurrentState::Id));

    mockContext.ClearDirtyList();
    // Invalid position
    GenericDimensionStateStruct InvalidCurrentState{ Optional<Percent100ths>(10001), Optional<bool>(false),
                                                     Optional<Globals::ThreeLevelAutoEnum>(Globals::ThreeLevelAutoEnum::kLow) };
    DataModel::Nullable<GenericDimensionStateStruct> testInvalid(InvalidCurrentState);
    EXPECT_EQ(logic->SetCurrentState(testInvalid), CHIP_ERROR_INVALID_ARGUMENT);

    // Ensure the value wasn't changed
    EXPECT_EQ(logic->GetCurrentState(currentState), CHIP_NO_ERROR);
    EXPECT_EQ(currentState, testCurrentState);
    EXPECT_FALSE(HasAttributeChanges(mockContext.GetDirtyList(), Attributes::CurrentState::Id));

    // Invalid speed
    InvalidCurrentState.Set(Optional<Percent100ths>(10000), Optional<bool>(false),
                            Optional<Globals::ThreeLevelAutoEnum>(Globals::ThreeLevelAutoEnum::kUnknownEnumValue));
    testInvalid.SetNonNull(InvalidCurrentState);
    EXPECT_EQ(logic->SetCurrentState(testInvalid), CHIP_ERROR_INVALID_ARGUMENT);
    // Ensure the value wasn't changed
    EXPECT_EQ(logic->GetCurrentState(currentState), CHIP_NO_ERROR);
    EXPECT_EQ(currentState, testCurrentState);
    EXPECT_FALSE(HasAttributeChanges(mockContext.GetDirtyList(), Attributes::CurrentState::Id));
}

//=========================================================================================
// Tests for Target Attribute
//=========================================================================================

// This test ensures that the set/get of Target without Intialisation
// - should return CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE
TEST_F(TestClosureDimensionClusterLogic, TestTargetWithNoIntialisation)
{
    GenericDimensionStateStruct testTargetStruct{ Optional<Percent100ths>(0), Optional<bool>(false),
                                                  Optional<Globals::ThreeLevelAutoEnum>(Globals::ThreeLevelAutoEnum::kAuto) };

    DataModel::Nullable<GenericDimensionStateStruct> testTarget(testTargetStruct);
    DataModel::Nullable<GenericDimensionStateStruct> target;

    mockContext.ClearDirtyList();
    EXPECT_EQ(logic->GetTargetState(target), CHIP_ERROR_INCORRECT_STATE);
    EXPECT_EQ(logic->SetTargetState(testTarget), CHIP_ERROR_INCORRECT_STATE);
    EXPECT_FALSE(HasAttributeChanges(mockContext.GetDirtyList(), Attributes::TargetState::Id));
}

// This test ensures that the set of Target without Positioning feature
// - should return CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE if position feild is present
// - should return CHIP_NO_ERROR if position feild is abscent
TEST_F(TestClosureDimensionClusterLogic, TestTargetWithNoPositioningFeature)
{
    GenericDimensionStateStruct testTargetStruct{ Optional<Percent100ths>(0), Optional<bool>(false),
                                                  Optional<Globals::ThreeLevelAutoEnum>(Globals::ThreeLevelAutoEnum::kAuto) };

    DataModel::Nullable<GenericDimensionStateStruct> testTarget(testTargetStruct);
    DataModel::Nullable<GenericDimensionStateStruct> target;

    conformance.FeatureMap().Set(Feature::kMotionLatching);

    EXPECT_EQ(logic->Init(conformance, initParams), CHIP_NO_ERROR);
    mockContext.ClearDirtyList();

    // Get default value
    EXPECT_EQ(logic->GetTargetState(target), CHIP_NO_ERROR);
    EXPECT_EQ(target, DataModel::NullNullable);

    // Set current state will with position field without positioning
    EXPECT_EQ(logic->SetTargetState(testTarget), CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE);
    EXPECT_EQ(logic->GetTargetState(target), CHIP_NO_ERROR);
    EXPECT_EQ(target, DataModel::NullNullable);
    EXPECT_FALSE(HasAttributeChanges(mockContext.GetDirtyList(), Attributes::TargetState::Id));

    // Set currentstate without position
    //  we set speed aslo NULL as speed feature is positioning optional.
    testTargetStruct.Set(NullOptional, Optional<bool>(false), NullOptional);
    testTarget.SetNonNull(testTargetStruct);
    EXPECT_EQ(logic->SetTargetState(testTarget), CHIP_NO_ERROR);
    EXPECT_EQ(logic->GetTargetState(target), CHIP_NO_ERROR);
    EXPECT_EQ(target, testTarget);
    EXPECT_TRUE(HasAttributeChanges(mockContext.GetDirtyList(), Attributes::TargetState::Id));
}

// This test ensures that the set of Target without MotionLatching feature
// - should return CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE if latch feild is present
// - should return CHIP_NO_ERROR if latch feild is abscent
TEST_F(TestClosureDimensionClusterLogic, TestTargetWithNoMotionLatchingFeature)
{
    GenericDimensionStateStruct testTargetStruct{ Optional<Percent100ths>(0), Optional<bool>(false),
                                                  Optional<Globals::ThreeLevelAutoEnum>(Globals::ThreeLevelAutoEnum::kAuto) };

    DataModel::Nullable<GenericDimensionStateStruct> testTarget(testTargetStruct);
    DataModel::Nullable<GenericDimensionStateStruct> target;

    conformance.FeatureMap().Set(Feature::kPositioning).Set(Feature::kSpeed);

    EXPECT_EQ(logic->Init(conformance, initParams), CHIP_NO_ERROR);
    mockContext.ClearDirtyList();

    // Get default value
    EXPECT_EQ(logic->GetTargetState(target), CHIP_NO_ERROR);
    EXPECT_EQ(target, DataModel::NullNullable);

    // Set current state will with position field without positioning
    EXPECT_EQ(logic->SetTargetState(testTarget), CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE);
    EXPECT_EQ(logic->GetTargetState(target), CHIP_NO_ERROR);
    EXPECT_EQ(target, DataModel::NullNullable);
    EXPECT_FALSE(HasAttributeChanges(mockContext.GetDirtyList(), Attributes::TargetState::Id));

    // Set currentstate without position
    //  we set speed aslo NULL as speed feature is positioning optional.
    testTargetStruct.Set(Optional<Percent100ths>(0), NullOptional,
                         Optional<Globals::ThreeLevelAutoEnum>(Globals::ThreeLevelAutoEnum::kAuto));
    testTarget.SetNonNull(testTargetStruct);
    EXPECT_EQ(logic->SetTargetState(testTarget), CHIP_NO_ERROR);
    EXPECT_EQ(logic->GetTargetState(target), CHIP_NO_ERROR);
    EXPECT_EQ(target, testTarget);
    EXPECT_TRUE(HasAttributeChanges(mockContext.GetDirtyList(), Attributes::TargetState::Id));
}

// This test ensures that the set of Target without Speed feature
// - should return CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE if speed field is present
// - should return CHIP_NO_ERROR if speed field is abscent
TEST_F(TestClosureDimensionClusterLogic, TestTargetWithNoSpeedFeature)
{
    GenericDimensionStateStruct testTargetStruct{ Optional<Percent100ths>(0), Optional<bool>(false),
                                                  Optional<Globals::ThreeLevelAutoEnum>(Globals::ThreeLevelAutoEnum::kAuto) };

    DataModel::Nullable<GenericDimensionStateStruct> testTarget(testTargetStruct);
    DataModel::Nullable<GenericDimensionStateStruct> target;

    conformance.FeatureMap().Set(Feature::kPositioning).Set(Feature::kMotionLatching);

    EXPECT_EQ(logic->Init(conformance, initParams), CHIP_NO_ERROR);
    mockContext.ClearDirtyList();

    // Get default value
    EXPECT_EQ(logic->GetTargetState(target), CHIP_NO_ERROR);
    EXPECT_EQ(target, DataModel::NullNullable);

    // Set current state will with position field without positioning
    EXPECT_EQ(logic->SetTargetState(testTarget), CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE);
    EXPECT_EQ(logic->GetTargetState(target), CHIP_NO_ERROR);
    EXPECT_EQ(target, DataModel::NullNullable);
    EXPECT_FALSE(HasAttributeChanges(mockContext.GetDirtyList(), Attributes::TargetState::Id));

    // Set currentstate without position
    //  we set speed aslo NULL as speed feature is positioning optional.
    testTargetStruct.Set(Optional<Percent100ths>(0), Optional<bool>(false), NullOptional);
    testTarget.SetNonNull(testTargetStruct);
    EXPECT_EQ(logic->SetTargetState(testTarget), CHIP_NO_ERROR);
    EXPECT_EQ(logic->GetTargetState(target), CHIP_NO_ERROR);
    EXPECT_EQ(target, testTarget);
    EXPECT_TRUE(HasAttributeChanges(mockContext.GetDirtyList(), Attributes::TargetState::Id));
}

// This test ensures that the Setter and getter for currentstate
// - sets/gets value.
// - return CHIP_ERROR_INVALID_ARGUMENT constraints checks
TEST_F(TestClosureDimensionClusterLogic, TestTarget)
{
    conformance.FeatureMap().Set(Feature::kPositioning).Set(Feature::kMotionLatching).Set(Feature::kSpeed);

    EXPECT_EQ(logic->Init(conformance, initParams), CHIP_NO_ERROR);
    mockContext.ClearDirtyList();

    GenericDimensionStateStruct testTargetStruct{ Optional<Percent100ths>(0), Optional<bool>(false),
                                                  Optional<Globals::ThreeLevelAutoEnum>(Globals::ThreeLevelAutoEnum::kAuto) };

    DataModel::Nullable<GenericDimensionStateStruct> testTarget(testTargetStruct);
    DataModel::Nullable<GenericDimensionStateStruct> target;

    EXPECT_EQ(logic->GetTargetState(target), CHIP_NO_ERROR);
    EXPECT_EQ(target, DataModel::NullNullable);

    // set Values
    EXPECT_EQ(logic->SetTargetState(testTarget), CHIP_NO_ERROR);
    // Ensure the value is accessible via the API
    EXPECT_EQ(logic->GetTargetState(target), CHIP_NO_ERROR);
    EXPECT_EQ(target, testTarget);
    EXPECT_TRUE(HasAttributeChanges(mockContext.GetDirtyList(), Attributes::TargetState::Id));

    mockContext.ClearDirtyList();
    // Change values
    testTargetStruct.Set(Optional<Percent100ths>(10000), Optional<bool>(true),
                         Optional<Globals::ThreeLevelAutoEnum>(Globals::ThreeLevelAutoEnum::kHigh));
    testTarget.SetNonNull(testTargetStruct);
    EXPECT_EQ(logic->SetTargetState(testTarget), CHIP_NO_ERROR);
    EXPECT_EQ(logic->GetTargetState(target), CHIP_NO_ERROR);
    EXPECT_EQ(target, testTarget);
    EXPECT_TRUE(HasAttributeChanges(mockContext.GetDirtyList(), Attributes::TargetState::Id));

    mockContext.ClearDirtyList();
    // Change to NULL
    testTarget.SetNull();
    EXPECT_EQ(logic->SetTargetState(testTarget), CHIP_NO_ERROR);
    EXPECT_EQ(logic->GetTargetState(target), CHIP_NO_ERROR);
    EXPECT_EQ(target, DataModel::NullNullable);
    EXPECT_TRUE(HasAttributeChanges(mockContext.GetDirtyList(), Attributes::TargetState::Id));

    mockContext.ClearDirtyList();
    // set NULL value again
    testTarget.SetNull();
    EXPECT_EQ(logic->SetTargetState(testTarget), CHIP_NO_ERROR);
    EXPECT_EQ(logic->GetTargetState(target), CHIP_NO_ERROR);
    EXPECT_EQ(target, DataModel::NullNullable);
    EXPECT_FALSE(HasAttributeChanges(mockContext.GetDirtyList(), Attributes::TargetState::Id));

    mockContext.ClearDirtyList();
    // Change from NULL
    testTargetStruct.Set(Optional<Percent100ths>(5000), Optional<bool>(false),
                         Optional<Globals::ThreeLevelAutoEnum>(Globals::ThreeLevelAutoEnum::kMedium));
    testTarget.SetNonNull(testTargetStruct);
    EXPECT_EQ(logic->SetTargetState(testTarget), CHIP_NO_ERROR);
    EXPECT_EQ(logic->GetTargetState(target), CHIP_NO_ERROR);
    EXPECT_EQ(target, testTarget);
    EXPECT_TRUE(HasAttributeChanges(mockContext.GetDirtyList(), Attributes::TargetState::Id));

    mockContext.ClearDirtyList();
    // Invalid position
    GenericDimensionStateStruct InvalidTarget{ Optional<Percent100ths>(10001), Optional<bool>(false),
                                               Optional<Globals::ThreeLevelAutoEnum>(Globals::ThreeLevelAutoEnum::kLow) };
    DataModel::Nullable<GenericDimensionStateStruct> testInvalid(InvalidTarget);
    EXPECT_EQ(logic->SetTargetState(testInvalid), CHIP_ERROR_INVALID_ARGUMENT);

    // Ensure the value wasn't changed
    EXPECT_EQ(logic->GetTargetState(target), CHIP_NO_ERROR);
    EXPECT_EQ(target, testTarget);
    EXPECT_FALSE(HasAttributeChanges(mockContext.GetDirtyList(), Attributes::TargetState::Id));

    // Invalid speed
    InvalidTarget.Set(Optional<Percent100ths>(10000), Optional<bool>(false),
                      Optional<Globals::ThreeLevelAutoEnum>(Globals::ThreeLevelAutoEnum::kUnknownEnumValue));
    testInvalid.SetNonNull(InvalidTarget);
    EXPECT_EQ(logic->SetTargetState(testInvalid), CHIP_ERROR_INVALID_ARGUMENT);
    // Ensure the value wasn't changed
    EXPECT_EQ(logic->GetTargetState(target), CHIP_NO_ERROR);
    EXPECT_EQ(target, testTarget);
    EXPECT_FALSE(HasAttributeChanges(mockContext.GetDirtyList(), Attributes::TargetState::Id));
}

//=========================================================================================
// Tests for Resolution Attribute
//=========================================================================================

// This test ensures that the set/get of Target without Intialisation
// - should return CHIP_ERROR_INCORRECT_STATE
TEST_F(TestClosureDimensionClusterLogic, TestResolutionWithNoIntialisation)
{
    Percent100ths testResolution = 100;
    Percent100ths resolution;

    mockContext.ClearDirtyList();

    EXPECT_EQ(logic->GetResolution(resolution), CHIP_ERROR_INCORRECT_STATE);
    EXPECT_EQ(logic->SetResolution(testResolution), CHIP_ERROR_INCORRECT_STATE);
    EXPECT_FALSE(HasAttributeChanges(mockContext.GetDirtyList(), Attributes::Resolution::Id));
}

// This test ensures that the Resolution without Positioning feature
// - should return CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE if position feild is present
TEST_F(TestClosureDimensionClusterLogic, TestResolutionWithNoPositioningFeature)
{
    conformance.FeatureMap().Set(Feature::kMotionLatching);

    Percent100ths testResolution = 100;
    Percent100ths resolution;

    EXPECT_EQ(logic->Init(conformance, initParams), CHIP_NO_ERROR);
    mockContext.ClearDirtyList();

    EXPECT_EQ(logic->GetResolution(resolution), CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE);
    EXPECT_EQ(logic->SetResolution(testResolution), CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE);
    EXPECT_FALSE(HasAttributeChanges(mockContext.GetDirtyList(), Attributes::Resolution::Id));
}

// This test ensures that the Setter and getter of Resolution can
// - set/get value.
// - return CHIP_ERROR_INVALID_ARGUMENT constraints checks
TEST_F(TestClosureDimensionClusterLogic, TestResolution)
{
    conformance.FeatureMap().Set(Feature::kPositioning);

    EXPECT_EQ(logic->Init(conformance, initParams), CHIP_NO_ERROR);
    mockContext.ClearDirtyList();

    Percent100ths testResolution = 10;
    Percent100ths Resolution;

    // get default value
    EXPECT_EQ(logic->GetResolution(Resolution), CHIP_NO_ERROR);
    EXPECT_EQ(Resolution, 1);

    // change Value
    EXPECT_EQ(logic->SetResolution(testResolution), CHIP_NO_ERROR);
    EXPECT_TRUE(HasAttributeChanges(mockContext.GetDirtyList(), Attributes::Resolution::Id));

    // get changed Value
    EXPECT_EQ(logic->GetResolution(Resolution), CHIP_NO_ERROR);
    EXPECT_EQ(Resolution, testResolution);

    mockContext.ClearDirtyList();
    // Invalid Resolution
    Percent100ths invalidResolution = 10001;
    EXPECT_EQ(logic->SetResolution(invalidResolution), CHIP_ERROR_INVALID_ARGUMENT);
    EXPECT_FALSE(HasAttributeChanges(mockContext.GetDirtyList(), Attributes::Resolution::Id));
    // Ensure the value wasn't changed
    EXPECT_EQ(logic->GetResolution(Resolution), CHIP_NO_ERROR);
    EXPECT_EQ(Resolution, testResolution);

    mockContext.ClearDirtyList();
    // Invalid Resolution
    invalidResolution = 0;
    EXPECT_EQ(logic->SetResolution(invalidResolution), CHIP_ERROR_INVALID_ARGUMENT);
    EXPECT_FALSE(HasAttributeChanges(mockContext.GetDirtyList(), Attributes::Resolution::Id));
    // Ensure the value wasn't changed
    EXPECT_EQ(logic->GetResolution(Resolution), CHIP_NO_ERROR);
    EXPECT_EQ(Resolution, testResolution);
}

//=========================================================================================
// Tests for StepValue Attribute
//=========================================================================================

// This test ensures that the set/get of StepValue without Intialisation
// - should return CHIP_ERROR_INCORRECT_STATE
TEST_F(TestClosureDimensionClusterLogic, TestStepValueWithNoIntialisation)
{
    Percent100ths testStepValue = 100;
    Percent100ths stepValue;

    mockContext.ClearDirtyList();

    EXPECT_EQ(logic->GetResolution(stepValue), CHIP_ERROR_INCORRECT_STATE);
    EXPECT_EQ(logic->SetResolution(testStepValue), CHIP_ERROR_INCORRECT_STATE);
    EXPECT_FALSE(HasAttributeChanges(mockContext.GetDirtyList(), Attributes::StepValue::Id));
}

// This test ensures that the StepValue without Positioning feature
// - should return CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE
TEST_F(TestClosureDimensionClusterLogic, TestStepValueWithNoPositioningFeature)
{
    conformance.FeatureMap().Set(Feature::kMotionLatching);

    Percent100ths testStepValue = 100;
    Percent100ths stepValue;

    EXPECT_EQ(logic->Init(conformance, initParams), CHIP_NO_ERROR);
    mockContext.ClearDirtyList();

    EXPECT_EQ(logic->GetResolution(stepValue), CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE);
    EXPECT_EQ(logic->SetResolution(testStepValue), CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE);
    EXPECT_FALSE(HasAttributeChanges(mockContext.GetDirtyList(), Attributes::StepValue::Id));
}

// This test ensures that the Setter and getter of StepValue can
// - set/get value.
// - return CHIP_ERROR_INVALID_ARGUMENT constraints checks
TEST_F(TestClosureDimensionClusterLogic, TestStepValue)
{
    conformance.FeatureMap().Set(Feature::kPositioning).Set(Feature::kRotation);

    initParams.modulationType       = ModulationTypeEnum::kOpacity;
    initParams.rotationAxis         = RotationAxisEnum::kBottom;
    initParams.translationDirection = TranslationDirectionEnum::kBackward;

    EXPECT_EQ(logic->Init(conformance, initParams), CHIP_NO_ERROR);
    mockContext.ClearDirtyList();

    Percent100ths testStepValue = 10;
    Percent100ths StepValue;

    // Check Default value
    EXPECT_EQ(logic->GetStepValue(StepValue), CHIP_NO_ERROR);
    EXPECT_EQ(StepValue, 1);

    // set Value
    EXPECT_EQ(logic->SetStepValue(testStepValue), CHIP_NO_ERROR);
    EXPECT_TRUE(HasAttributeChanges(mockContext.GetDirtyList(), Attributes::StepValue::Id));

    // Ensure the value is accessible via the API
    EXPECT_EQ(logic->GetStepValue(StepValue), CHIP_NO_ERROR);
    EXPECT_EQ(StepValue, testStepValue);

    mockContext.ClearDirtyList();
    // Change values
    testStepValue = 100;
    EXPECT_EQ(logic->SetStepValue(testStepValue), CHIP_NO_ERROR);
    EXPECT_EQ(logic->GetStepValue(StepValue), CHIP_NO_ERROR);
    EXPECT_EQ(StepValue, testStepValue);
    EXPECT_TRUE(HasAttributeChanges(mockContext.GetDirtyList(), Attributes::StepValue::Id));

    mockContext.ClearDirtyList();
    // Invalid StepValue
    Percent100ths invalidStepValue = 10001;
    EXPECT_EQ(logic->SetStepValue(invalidStepValue), CHIP_ERROR_INVALID_ARGUMENT);
    // Ensure the value wasn't changed
    EXPECT_EQ(logic->GetStepValue(StepValue), CHIP_NO_ERROR);
    EXPECT_FALSE(HasAttributeChanges(mockContext.GetDirtyList(), Attributes::StepValue::Id));
    EXPECT_EQ(StepValue, testStepValue);

    mockContext.ClearDirtyList();
    // StepValue not Multiple of Resolution
    invalidStepValue         = 45;
    Percent100ths resolution = 10;
    EXPECT_EQ(logic->SetResolution(resolution), CHIP_NO_ERROR);
    EXPECT_EQ(logic->SetStepValue(invalidStepValue), CHIP_ERROR_INVALID_ARGUMENT);
    // Ensure the value wasn't changed
    EXPECT_EQ(logic->GetStepValue(StepValue), CHIP_NO_ERROR);
    EXPECT_FALSE(HasAttributeChanges(mockContext.GetDirtyList(), Attributes::StepValue::Id));
    EXPECT_EQ(StepValue, testStepValue);
}

//=========================================================================================
// Tests for Unit Attribute
//=========================================================================================

// This test ensures that the set/get of Unit without Intialisation
// - should return CHIP_ERROR_INCORRECT_STATE
TEST_F(TestClosureDimensionClusterLogic, TestUnitWithNoIntialisation)
{
    ClosureUnitEnum testUnit = ClosureUnitEnum::kDegree;
    ClosureUnitEnum unit;

    mockContext.ClearDirtyList();

    EXPECT_EQ(logic->GetUnit(unit), CHIP_ERROR_INCORRECT_STATE);
    EXPECT_EQ(logic->SetUnit(testUnit), CHIP_ERROR_INCORRECT_STATE);
    EXPECT_FALSE(HasAttributeChanges(mockContext.GetDirtyList(), Attributes::Unit::Id));
}

// This test ensures that the Unit without Unit feature
// - should return CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE
TEST_F(TestClosureDimensionClusterLogic, TestUnitWithNoUnitFeature)
{
    conformance.FeatureMap().Set(Feature::kPositioning).Set(Feature::kMotionLatching);

    ClosureUnitEnum testUnit = ClosureUnitEnum::kDegree;
    ClosureUnitEnum unit;

    EXPECT_EQ(logic->Init(conformance, initParams), CHIP_NO_ERROR);
    mockContext.ClearDirtyList();

    EXPECT_EQ(logic->GetUnit(unit), CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE);
    EXPECT_EQ(logic->SetUnit(testUnit), CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE);
    EXPECT_FALSE(HasAttributeChanges(mockContext.GetDirtyList(), Attributes::Unit::Id));
}

// This test ensures that the Setter and getter of Unit can
// - set/get value.
// - return CHIP_ERROR_INVALID_ARGUMENT constraints checks
TEST_F(TestClosureDimensionClusterLogic, TestUnit)
{
    conformance.FeatureMap().Set(Feature::kPositioning).Set(Feature::kUnit);

    initParams.modulationType       = ModulationTypeEnum::kOpacity;
    initParams.rotationAxis         = RotationAxisEnum::kBottom;
    initParams.translationDirection = TranslationDirectionEnum::kBackward;

    EXPECT_EQ(logic->Init(conformance, initParams), CHIP_NO_ERROR);
    mockContext.ClearDirtyList();

    ClosureUnitEnum testUnit = ClosureUnitEnum::kDegree;
    ClosureUnitEnum Unit;

    // Default value
    EXPECT_EQ(logic->GetUnit(Unit), CHIP_NO_ERROR);
    EXPECT_EQ(Unit, ClosureUnitEnum::kUnknownEnumValue);

    // set Values
    EXPECT_EQ(logic->SetUnit(testUnit), CHIP_NO_ERROR);
    EXPECT_TRUE(HasAttributeChanges(mockContext.GetDirtyList(), Attributes::Unit::Id));
    // Ensure the value is accessible via the API
    EXPECT_EQ(logic->GetUnit(Unit), CHIP_NO_ERROR);
    EXPECT_EQ(Unit, testUnit);

    mockContext.ClearDirtyList();
    // Change values
    testUnit = ClosureUnitEnum::kMillimeter;
    EXPECT_EQ(logic->SetUnit(testUnit), CHIP_NO_ERROR);
    EXPECT_EQ(logic->GetUnit(Unit), CHIP_NO_ERROR);
    EXPECT_EQ(Unit, testUnit);
    EXPECT_TRUE(HasAttributeChanges(mockContext.GetDirtyList(), Attributes::Unit::Id));

    mockContext.ClearDirtyList();
    // Invalid Unit
    ClosureUnitEnum invalidUnit = ClosureUnitEnum::kUnknownEnumValue;
    EXPECT_EQ(logic->SetUnit(invalidUnit), CHIP_ERROR_INVALID_ARGUMENT);
    // Ensure the value wasn't changed
    EXPECT_EQ(logic->GetUnit(Unit), CHIP_NO_ERROR);
    EXPECT_EQ(Unit, testUnit);
    EXPECT_FALSE(HasAttributeChanges(mockContext.GetDirtyList(), Attributes::Unit::Id));
}

//=========================================================================================
// Tests for UnitRange Attribute
//=========================================================================================

// This test ensures that the set/get of UnitRange without Intialisation
// - should return CHIP_ERROR_INCORRECT_STATE
TEST_F(TestClosureDimensionClusterLogic, TestUnitRangeWithNoIntialisation)
{
    Structs::UnitRangeStruct::Type tUnitRange = { .min = 0, .max = 10000 };
    DataModel::Nullable<Structs::UnitRangeStruct::Type> testUnitRange{ tUnitRange };
    DataModel::Nullable<Structs::UnitRangeStruct::Type> unitRange;

    mockContext.ClearDirtyList();

    EXPECT_EQ(logic->GetUnitRange(unitRange), CHIP_ERROR_INCORRECT_STATE);
    EXPECT_EQ(logic->SetUnitRange(testUnitRange), CHIP_ERROR_INCORRECT_STATE);
    EXPECT_FALSE(HasAttributeChanges(mockContext.GetDirtyList(), Attributes::UnitRange::Id));
}

// This test ensures that the UnitRange without Unit feature
// - should return CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE
TEST_F(TestClosureDimensionClusterLogic, TestUnitRangeWithNoUnitFeature)
{
    conformance.FeatureMap().Set(Feature::kPositioning).Set(Feature::kMotionLatching);

    Structs::UnitRangeStruct::Type tUnitRange = { .min = 0, .max = 10000 };
    DataModel::Nullable<Structs::UnitRangeStruct::Type> testUnitRange{ tUnitRange };
    DataModel::Nullable<Structs::UnitRangeStruct::Type> unitRange;

    EXPECT_EQ(logic->Init(conformance, initParams), CHIP_NO_ERROR);
    mockContext.ClearDirtyList();

    EXPECT_EQ(logic->GetUnitRange(unitRange), CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE);
    EXPECT_EQ(logic->SetUnitRange(testUnitRange), CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE);
    EXPECT_FALSE(HasAttributeChanges(mockContext.GetDirtyList(), Attributes::UnitRange::Id));
}

// This test ensures that the Setter and getter of UnitRange can
// - set/get value.
// - return CHIP_ERROR_INVALID_ARGUMENT constraints checks
TEST_F(TestClosureDimensionClusterLogic, TestUnitRange)
{
    conformance.FeatureMap().Set(Feature::kPositioning).Set(Feature::kUnit);

    EXPECT_EQ(logic->Init(conformance, initParams), CHIP_NO_ERROR);
    mockContext.ClearDirtyList();

    Structs::UnitRangeStruct::Type tUnitRange       = { .min = 0, .max = 10000 };
    Structs::UnitRangeStruct::Type newUnitRange     = { .min = 10, .max = 100 };
    Structs::UnitRangeStruct::Type invalidUnitRange = { .min = 1000, .max = 10 };
    DataModel::Nullable<Structs::UnitRangeStruct::Type> testUnitRange{ tUnitRange };
    DataModel::Nullable<Structs::UnitRangeStruct::Type> UnitRange;

    // Default Value
    EXPECT_EQ(logic->GetUnitRange(UnitRange), CHIP_NO_ERROR);
    EXPECT_EQ(UnitRange.IsNull(), true);

    // set Values
    EXPECT_EQ(logic->SetUnitRange(testUnitRange), CHIP_NO_ERROR);

    // Ensure the value is accessible via the API
    EXPECT_EQ(logic->GetUnitRange(UnitRange), CHIP_NO_ERROR);
    EXPECT_EQ(UnitRange.Value().min, testUnitRange.Value().min);
    EXPECT_EQ(UnitRange.Value().max, testUnitRange.Value().max);
    EXPECT_TRUE(HasAttributeChanges(mockContext.GetDirtyList(), Attributes::UnitRange::Id));

    mockContext.ClearDirtyList();
    // Change values
    testUnitRange = DataModel::Nullable<Structs::UnitRangeStruct::Type>(newUnitRange);
    EXPECT_EQ(logic->SetUnitRange(testUnitRange), CHIP_NO_ERROR);
    EXPECT_EQ(logic->GetUnitRange(UnitRange), CHIP_NO_ERROR);
    EXPECT_EQ(UnitRange.Value().min, testUnitRange.Value().min);
    EXPECT_EQ(UnitRange.Value().max, testUnitRange.Value().max);
    EXPECT_TRUE(HasAttributeChanges(mockContext.GetDirtyList(), Attributes::UnitRange::Id));

    mockContext.ClearDirtyList();
    // Change to Null, when present UnitRange is not NULL
    testUnitRange.SetNull();
    EXPECT_EQ(logic->SetUnitRange(testUnitRange), CHIP_NO_ERROR);
    EXPECT_EQ(logic->GetUnitRange(UnitRange), CHIP_NO_ERROR);
    EXPECT_EQ(UnitRange.IsNull(), true);
    EXPECT_TRUE(HasAttributeChanges(mockContext.GetDirtyList(), Attributes::UnitRange::Id));

    mockContext.ClearDirtyList();
    // Change to Null, when present UnitRange is NULL
    testUnitRange.SetNull();
    EXPECT_EQ(logic->SetUnitRange(testUnitRange), CHIP_NO_ERROR);
    EXPECT_EQ(logic->GetUnitRange(UnitRange), CHIP_NO_ERROR);
    EXPECT_EQ(UnitRange.IsNull(), true);
    EXPECT_FALSE(HasAttributeChanges(mockContext.GetDirtyList(), Attributes::UnitRange::Id));

    mockContext.ClearDirtyList();
    // valid degree Values
    EXPECT_EQ(logic->SetUnit(ClosureUnitEnum::kDegree), CHIP_NO_ERROR);
    newUnitRange.max = 90;
    newUnitRange.min = -90;
    testUnitRange    = DataModel::Nullable<Structs::UnitRangeStruct::Type>(newUnitRange);
    EXPECT_EQ(logic->SetUnitRange(testUnitRange), CHIP_NO_ERROR);
    EXPECT_TRUE(HasAttributeChanges(mockContext.GetDirtyList(), Attributes::UnitRange::Id));

    mockContext.ClearDirtyList();
    // Invalid Values
    testUnitRange = DataModel::Nullable<Structs::UnitRangeStruct::Type>(invalidUnitRange);
    EXPECT_EQ(logic->SetUnitRange(testUnitRange), CHIP_ERROR_INVALID_ARGUMENT);
    EXPECT_FALSE(HasAttributeChanges(mockContext.GetDirtyList(), Attributes::UnitRange::Id));

    mockContext.ClearDirtyList();
    // Invalid millimeter Values
    EXPECT_EQ(logic->SetUnit(ClosureUnitEnum::kMillimeter), CHIP_NO_ERROR);
    invalidUnitRange.max = 0;
    invalidUnitRange.min = 10000;
    testUnitRange        = DataModel::Nullable<Structs::UnitRangeStruct::Type>(invalidUnitRange);
    EXPECT_EQ(logic->SetUnitRange(testUnitRange), CHIP_ERROR_INVALID_ARGUMENT);
    EXPECT_FALSE(HasAttributeChanges(mockContext.GetDirtyList(), Attributes::UnitRange::Id));

    mockContext.ClearDirtyList();
    // Invalid millimeter Values
    EXPECT_EQ(logic->SetUnit(ClosureUnitEnum::kMillimeter), CHIP_NO_ERROR);
    invalidUnitRange.max = 10000;
    invalidUnitRange.min = -1;
    testUnitRange        = DataModel::Nullable<Structs::UnitRangeStruct::Type>(invalidUnitRange);
    EXPECT_EQ(logic->SetUnitRange(testUnitRange), CHIP_ERROR_INVALID_ARGUMENT);
    EXPECT_FALSE(HasAttributeChanges(mockContext.GetDirtyList(), Attributes::UnitRange::Id));

    mockContext.ClearDirtyList();
    // Invalid millimeter Values
    EXPECT_EQ(logic->SetUnit(ClosureUnitEnum::kMillimeter), CHIP_NO_ERROR);
    invalidUnitRange.max = -1;
    invalidUnitRange.min = 1000;
    testUnitRange        = DataModel::Nullable<Structs::UnitRangeStruct::Type>(invalidUnitRange);
    EXPECT_EQ(logic->SetUnitRange(testUnitRange), CHIP_ERROR_INVALID_ARGUMENT);
    EXPECT_FALSE(HasAttributeChanges(mockContext.GetDirtyList(), Attributes::UnitRange::Id));

    mockContext.ClearDirtyList();
    // Invalid degree Values
    EXPECT_EQ(logic->SetUnit(ClosureUnitEnum::kDegree), CHIP_NO_ERROR);
    invalidUnitRange.max = 390;
    invalidUnitRange.min = 0;
    testUnitRange        = DataModel::Nullable<Structs::UnitRangeStruct::Type>(invalidUnitRange);
    EXPECT_EQ(logic->SetUnitRange(testUnitRange), CHIP_ERROR_INVALID_ARGUMENT);
    EXPECT_FALSE(HasAttributeChanges(mockContext.GetDirtyList(), Attributes::UnitRange::Id));

    mockContext.ClearDirtyList();
    // Invalid degree Values
    EXPECT_EQ(logic->SetUnit(ClosureUnitEnum::kDegree), CHIP_NO_ERROR);
    invalidUnitRange.max = -390;
    invalidUnitRange.min = 0;
    testUnitRange        = DataModel::Nullable<Structs::UnitRangeStruct::Type>(invalidUnitRange);
    EXPECT_EQ(logic->SetUnitRange(testUnitRange), CHIP_ERROR_INVALID_ARGUMENT);
    EXPECT_FALSE(HasAttributeChanges(mockContext.GetDirtyList(), Attributes::UnitRange::Id));

    mockContext.ClearDirtyList();
    // Invalid degree range
    EXPECT_EQ(logic->SetUnit(ClosureUnitEnum::kDegree), CHIP_NO_ERROR);
    invalidUnitRange.max = -180;
    invalidUnitRange.min = 270;
    testUnitRange        = DataModel::Nullable<Structs::UnitRangeStruct::Type>(invalidUnitRange);
    EXPECT_EQ(logic->SetUnitRange(testUnitRange), CHIP_ERROR_INVALID_ARGUMENT);
    EXPECT_FALSE(HasAttributeChanges(mockContext.GetDirtyList(), Attributes::UnitRange::Id));

    mockContext.ClearDirtyList();
    // Invalid degree Values
    EXPECT_EQ(logic->SetUnit(ClosureUnitEnum::kDegree), CHIP_NO_ERROR);
    invalidUnitRange.max = 90;
    invalidUnitRange.min = 180;
    testUnitRange        = DataModel::Nullable<Structs::UnitRangeStruct::Type>(invalidUnitRange);
    EXPECT_EQ(logic->SetUnitRange(testUnitRange), CHIP_ERROR_INVALID_ARGUMENT);
    EXPECT_FALSE(HasAttributeChanges(mockContext.GetDirtyList(), Attributes::UnitRange::Id));

    mockContext.ClearDirtyList();
    // Invalid degree range
    EXPECT_EQ(logic->SetUnit(ClosureUnitEnum::kDegree), CHIP_NO_ERROR);
    invalidUnitRange.max = 190;
    invalidUnitRange.min = -180;
    testUnitRange        = DataModel::Nullable<Structs::UnitRangeStruct::Type>(invalidUnitRange);
    EXPECT_EQ(logic->SetUnitRange(testUnitRange), CHIP_ERROR_INVALID_ARGUMENT);
    EXPECT_FALSE(HasAttributeChanges(mockContext.GetDirtyList(), Attributes::UnitRange::Id));
}

//=========================================================================================
// Tests for LimitRange Attribute
//=========================================================================================

// This test ensures that the set/get of LimitRange without Intialisation
// - should return CHIP_ERROR_INCORRECT_STATE
TEST_F(TestClosureDimensionClusterLogic, TestLimitRangeWithNoIntialisation)
{
    Structs::RangePercent100thsStruct::Type testLimitRange = { .min = 0, .max = 10000 };
    Structs::RangePercent100thsStruct::Type limitRange;

    mockContext.ClearDirtyList();

    EXPECT_EQ(logic->GetLimitRange(limitRange), CHIP_ERROR_INCORRECT_STATE);
    EXPECT_EQ(logic->SetLimitRange(testLimitRange), CHIP_ERROR_INCORRECT_STATE);
    EXPECT_FALSE(HasAttributeChanges(mockContext.GetDirtyList(), Attributes::UnitRange::Id));
}

// This test ensures that the LimitRange without Limitation feature
// - should return CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE
TEST_F(TestClosureDimensionClusterLogic, TestLimitRangeWithNoUnitFeature)
{
    conformance.FeatureMap().Set(Feature::kPositioning).Set(Feature::kMotionLatching);

    Structs::RangePercent100thsStruct::Type testLimitRange = { .min = 0, .max = 10000 };
    Structs::RangePercent100thsStruct::Type LimitRange;

    EXPECT_EQ(logic->Init(conformance, initParams), CHIP_NO_ERROR);
    mockContext.ClearDirtyList();

    EXPECT_EQ(logic->GetLimitRange(LimitRange), CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE);
    EXPECT_EQ(logic->SetLimitRange(testLimitRange), CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE);
    EXPECT_FALSE(HasAttributeChanges(mockContext.GetDirtyList(), Attributes::UnitRange::Id));
}

// This test ensures that the Setter and getter of LimitRange can
// - set/get value.
// - return CHIP_ERROR_INVALID_ARGUMENT constraints checks
TEST_F(TestClosureDimensionClusterLogic, TestLimitRange)
{
    conformance.FeatureMap().Set(Feature::kPositioning).Set(Feature::kLimitation);

    EXPECT_EQ(logic->Init(conformance, initParams), CHIP_NO_ERROR);
    mockContext.ClearDirtyList();

    Structs::RangePercent100thsStruct::Type testLimitRange = { .min = 0, .max = 10000 };
    Structs::RangePercent100thsStruct::Type LimitRange;

    // Default Values
    EXPECT_EQ(logic->GetLimitRange(LimitRange), CHIP_NO_ERROR);
    EXPECT_EQ(LimitRange.min, 0);
    EXPECT_EQ(LimitRange.max, 0);

    mockContext.ClearDirtyList();
    // set Values
    Percent100ths resolution = 1;
    EXPECT_EQ(logic->SetResolution(resolution), CHIP_NO_ERROR);
    EXPECT_EQ(logic->SetLimitRange(testLimitRange), CHIP_NO_ERROR);

    // Ensure the value is accessible via the API
    EXPECT_EQ(logic->GetLimitRange(LimitRange), CHIP_NO_ERROR);
    EXPECT_EQ(LimitRange.min, testLimitRange.min);
    EXPECT_EQ(LimitRange.max, testLimitRange.max);
    EXPECT_TRUE(HasAttributeChanges(mockContext.GetDirtyList(), Attributes::LimitRange::Id));

    mockContext.ClearDirtyList();
    // Change values
    testLimitRange = { .min = 10, .max = 100 };
    EXPECT_EQ(logic->SetLimitRange(testLimitRange), CHIP_NO_ERROR);
    EXPECT_EQ(logic->GetLimitRange(LimitRange), CHIP_NO_ERROR);
    EXPECT_EQ(LimitRange.min, testLimitRange.min);
    EXPECT_EQ(LimitRange.max, testLimitRange.max);
    EXPECT_TRUE(HasAttributeChanges(mockContext.GetDirtyList(), Attributes::LimitRange::Id));

    mockContext.ClearDirtyList();
    // Invalid Values
    testLimitRange = { .min = 10001, .max = 100 };
    EXPECT_EQ(logic->SetLimitRange(testLimitRange), CHIP_ERROR_INVALID_ARGUMENT);
    EXPECT_FALSE(HasAttributeChanges(mockContext.GetDirtyList(), Attributes::LimitRange::Id));
    testLimitRange = { .min = 100, .max = 10001 };
    EXPECT_EQ(logic->SetLimitRange(testLimitRange), CHIP_ERROR_INVALID_ARGUMENT);
    EXPECT_FALSE(HasAttributeChanges(mockContext.GetDirtyList(), Attributes::LimitRange::Id));
    testLimitRange = { .min = 10000, .max = 0 };
    EXPECT_EQ(logic->SetLimitRange(testLimitRange), CHIP_ERROR_INVALID_ARGUMENT);
    EXPECT_FALSE(HasAttributeChanges(mockContext.GetDirtyList(), Attributes::LimitRange::Id));
    resolution = 10;
    EXPECT_EQ(logic->SetResolution(resolution), CHIP_NO_ERROR);
    // LimitValue not multiple of resolution
    testLimitRange = { .min = 45, .max = 100 };
    EXPECT_EQ(logic->SetLimitRange(testLimitRange), CHIP_ERROR_INVALID_ARGUMENT);
    EXPECT_FALSE(HasAttributeChanges(mockContext.GetDirtyList(), Attributes::LimitRange::Id));
    testLimitRange = { .min = 40, .max = 105 };
    EXPECT_EQ(logic->SetLimitRange(testLimitRange), CHIP_ERROR_INVALID_ARGUMENT);
    EXPECT_FALSE(HasAttributeChanges(mockContext.GetDirtyList(), Attributes::LimitRange::Id));
}

//=========================================================================================
// Tests for TranslationDirection Attribute
//=========================================================================================

// This test ensures that the Setter and getter of TranslationDirection can
// - set/get value.
TEST_F(TestClosureDimensionClusterLogic, TestTranslationDirection)
{
    conformance.FeatureMap().Set(Feature::kPositioning).Set(Feature::kTranslation);

    initParams.translationDirection = TranslationDirectionEnum::kBackward;

    mockContext.ClearDirtyList();
    EXPECT_EQ(logic->Init(conformance, initParams), CHIP_NO_ERROR);

    TranslationDirectionEnum TranslationDirection;

    EXPECT_EQ(logic->GetTranslationDirection(TranslationDirection), CHIP_NO_ERROR);
    EXPECT_EQ(TranslationDirection, TranslationDirectionEnum::kBackward);
    EXPECT_TRUE(HasAttributeChanges(mockContext.GetDirtyList(), Attributes::TranslationDirection::Id));
}

// This test ensures that the Setter and getter of TranslationDirection can
// - return CHIP_ERROR_INVALID_ARGUMENT constraints checks
TEST_F(TestClosureDimensionClusterLogic, TestTranslationDirectionInvalidValue)
{
    conformance.FeatureMap().Set(Feature::kPositioning).Set(Feature::kTranslation);

    initParams.translationDirection = TranslationDirectionEnum::kUnknownEnumValue;

    mockContext.ClearDirtyList();
    EXPECT_EQ(logic->Init(conformance, initParams), CHIP_ERROR_INVALID_ARGUMENT);
    EXPECT_FALSE(HasAttributeChanges(mockContext.GetDirtyList(), Attributes::TranslationDirection::Id));
}

//=========================================================================================
// Tests for RotationAxis Attribute
//=========================================================================================

// This test ensures that the Setter and getter of RotationAxis can
// - set/get value.
TEST_F(TestClosureDimensionClusterLogic, TestRotationAxis)
{
    conformance.FeatureMap().Set(Feature::kPositioning).Set(Feature::kRotation);

    initParams.rotationAxis = RotationAxisEnum::kCenteredHorizontal;

    mockContext.ClearDirtyList();
    EXPECT_EQ(logic->Init(conformance, initParams), CHIP_NO_ERROR);

    RotationAxisEnum RotationAxis;

    EXPECT_EQ(logic->GetRotationAxis(RotationAxis), CHIP_NO_ERROR);
    EXPECT_EQ(RotationAxis, RotationAxisEnum::kCenteredHorizontal);
    EXPECT_TRUE(HasAttributeChanges(mockContext.GetDirtyList(), Attributes::RotationAxis::Id));
}

// This test ensures that the Setter and getter of RotationAxis can
// - return CHIP_ERROR_INVALID_ARGUMENT constraints checks
TEST_F(TestClosureDimensionClusterLogic, TestRotationAxisInvalidValue)
{
    conformance.FeatureMap().Set(Feature::kPositioning).Set(Feature::kRotation);

    initParams.rotationAxis = RotationAxisEnum::kUnknownEnumValue;

    mockContext.ClearDirtyList();
    EXPECT_EQ(logic->Init(conformance, initParams), CHIP_ERROR_INVALID_ARGUMENT);
    EXPECT_FALSE(HasAttributeChanges(mockContext.GetDirtyList(), Attributes::RotationAxis::Id));
}

//=========================================================================================
// Tests for ModulationType Attribute
//=========================================================================================

// This test ensures that the Setter and getter of ModulationType can
// - set/get value.
TEST_F(TestClosureDimensionClusterLogic, TestModulationType)
{
    conformance.FeatureMap().Set(Feature::kPositioning).Set(Feature::kModulation);

    initParams.modulationType = ModulationTypeEnum::kSlatsOpenwork;

    mockContext.ClearDirtyList();
    EXPECT_EQ(logic->Init(conformance, initParams), CHIP_NO_ERROR);

    ModulationTypeEnum ModulationType;

    EXPECT_EQ(logic->GetModulationType(ModulationType), CHIP_NO_ERROR);
    EXPECT_EQ(ModulationType, ModulationTypeEnum::kSlatsOpenwork);
    EXPECT_TRUE(HasAttributeChanges(mockContext.GetDirtyList(), Attributes::ModulationType::Id));
}

// This test ensures that the Setter and getter of ModulationType can
// - return CHIP_ERROR_INVALID_ARGUMENT constraints checks
TEST_F(TestClosureDimensionClusterLogic, TestModulationTypeInvalidValue)
{
    conformance.FeatureMap().Set(Feature::kPositioning).Set(Feature::kModulation);

    initParams.modulationType = ModulationTypeEnum::kUnknownEnumValue;

    mockContext.ClearDirtyList();
    EXPECT_EQ(logic->Init(conformance, initParams), CHIP_ERROR_INVALID_ARGUMENT);
    EXPECT_FALSE(HasAttributeChanges(mockContext.GetDirtyList(), Attributes::ModulationType::Id));
}

//=========================================================================================
// Tests for Overflow Attribute
//=========================================================================================

// This test ensures that the Setter and getter of Overflow can
// - set/get value.
// - constraints checks
TEST_F(TestClosureDimensionClusterLogic, TestOverflow)
{
    conformance.FeatureMap().Set(Feature::kPositioning).Set(Feature::kRotation);

    initParams.rotationAxis = RotationAxisEnum::kBottom;

    mockContext.ClearDirtyList();
    EXPECT_EQ(logic->Init(conformance, initParams), CHIP_NO_ERROR);

    OverflowEnum testOverflow = OverflowEnum::kBottomInside;
    OverflowEnum Overflow;

    // Default value
    EXPECT_EQ(logic->GetOverflow(Overflow), CHIP_NO_ERROR);
    EXPECT_EQ(Overflow, OverflowEnum::kUnknownEnumValue);

    mockContext.ClearDirtyList();
    // set Values
    EXPECT_EQ(logic->SetOverflow(testOverflow), CHIP_NO_ERROR);

    // Ensure the value is accessible via the API
    EXPECT_EQ(logic->GetOverflow(Overflow), CHIP_NO_ERROR);
    EXPECT_EQ(Overflow, testOverflow);
    EXPECT_TRUE(HasAttributeChanges(mockContext.GetDirtyList(), Attributes::Overflow::Id));

    mockContext.ClearDirtyList();
    // Change values
    testOverflow = OverflowEnum::kBottomOutside;
    EXPECT_EQ(logic->SetOverflow(testOverflow), CHIP_NO_ERROR);
    EXPECT_EQ(logic->GetOverflow(Overflow), CHIP_NO_ERROR);
    EXPECT_EQ(Overflow, testOverflow);
    EXPECT_TRUE(HasAttributeChanges(mockContext.GetDirtyList(), Attributes::Overflow::Id));

    mockContext.ClearDirtyList();
    // Invalid Overflow
    OverflowEnum invalidOverflow = OverflowEnum::kUnknownEnumValue;
    EXPECT_EQ(logic->SetOverflow(invalidOverflow), CHIP_ERROR_INVALID_ARGUMENT);
    // Ensure the value wasn't changed
    EXPECT_EQ(logic->GetOverflow(Overflow), CHIP_NO_ERROR);
    EXPECT_EQ(Overflow, testOverflow);
    EXPECT_FALSE(HasAttributeChanges(mockContext.GetDirtyList(), Attributes::Overflow::Id));
}

// This test ensures that the Set function
// - sets the value properly including
// - constraints checks
TEST_F(TestClosureDimensionClusterLogic, TestRotationOverflowDependency)
{
    conformance.FeatureMap().Set(Feature::kPositioning).Set(Feature::kRotation);

    initParams.rotationAxis = RotationAxisEnum::kCenteredHorizontal;

    mockContext.ClearDirtyList();
    EXPECT_EQ(logic->Init(conformance, initParams), CHIP_NO_ERROR);

    OverflowEnum testOverflow = OverflowEnum::kBottomInside;
    OverflowEnum Overflow;

    // Default value
    EXPECT_EQ(logic->GetOverflow(Overflow), CHIP_NO_ERROR);
    EXPECT_EQ(Overflow, OverflowEnum::kUnknownEnumValue);

    mockContext.ClearDirtyList();
    // set and get Values
    EXPECT_EQ(logic->SetOverflow(testOverflow), CHIP_NO_ERROR);
    EXPECT_EQ(logic->GetOverflow(Overflow), CHIP_NO_ERROR);
    EXPECT_EQ(Overflow, testOverflow);
    EXPECT_TRUE(HasAttributeChanges(mockContext.GetDirtyList(), Attributes::Overflow::Id));

    mockContext.ClearDirtyList();
    // Change values
    testOverflow = OverflowEnum::kTopOutside;
    EXPECT_EQ(logic->SetOverflow(testOverflow), CHIP_NO_ERROR);
    EXPECT_EQ(logic->GetOverflow(Overflow), CHIP_NO_ERROR);
    EXPECT_EQ(Overflow, testOverflow);
    EXPECT_TRUE(HasAttributeChanges(mockContext.GetDirtyList(), Attributes::Overflow::Id));

    mockContext.ClearDirtyList();
    // Invalid Overflow
    OverflowEnum invalidOverflow = OverflowEnum::kInside;
    EXPECT_EQ(logic->SetOverflow(invalidOverflow), CHIP_ERROR_INVALID_ARGUMENT);
    // Ensure the value wasn't changed
    EXPECT_EQ(logic->GetOverflow(Overflow), CHIP_NO_ERROR);
    EXPECT_EQ(Overflow, testOverflow);
    EXPECT_FALSE(HasAttributeChanges(mockContext.GetDirtyList(), Attributes::Overflow::Id));

    mockContext.ClearDirtyList();
    // Invalid Overflow
    invalidOverflow = OverflowEnum::kOutside;
    EXPECT_EQ(logic->SetOverflow(invalidOverflow), CHIP_ERROR_INVALID_ARGUMENT);
    // Ensure the value wasn't changed
    EXPECT_EQ(logic->GetOverflow(Overflow), CHIP_NO_ERROR);
    EXPECT_EQ(Overflow, testOverflow);
    EXPECT_FALSE(HasAttributeChanges(mockContext.GetDirtyList(), Attributes::Overflow::Id));

    mockContext.ClearDirtyList();
    // Invalid Overflow
    invalidOverflow = OverflowEnum::kNoOverflow;
    EXPECT_EQ(logic->SetOverflow(invalidOverflow), CHIP_ERROR_INVALID_ARGUMENT);
    // Ensure the value wasn't changed
    EXPECT_EQ(logic->GetOverflow(Overflow), CHIP_NO_ERROR);
    EXPECT_EQ(Overflow, testOverflow);
    EXPECT_FALSE(HasAttributeChanges(mockContext.GetDirtyList(), Attributes::Overflow::Id));
}

// This test ensures that the Set function
// Default value
// set fails with CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE
TEST_F(TestClosureDimensionClusterLogic, TestUnsupportedOverflow)
{
    conformance.FeatureMap().Set(Feature::kPositioning).Set(Feature::kModulation);

    initParams.modulationType = ModulationTypeEnum::kOpacity;

    mockContext.ClearDirtyList();
    EXPECT_EQ(logic->Init(conformance, initParams), CHIP_NO_ERROR);

    OverflowEnum testOverflow = OverflowEnum::kBottomInside;
    OverflowEnum overflow;
    ClusterState state;

    // Default value
    EXPECT_EQ(logic->GetOverflow(overflow), CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE);
    state = logic->GetState();
    EXPECT_EQ(state.overflow, OverflowEnum::kUnknownEnumValue);

    mockContext.ClearDirtyList();
    // set Values
    EXPECT_EQ(logic->SetOverflow(testOverflow), CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE);

    // Ensure the value is unaccessible via the API
    EXPECT_EQ(logic->GetOverflow(overflow), CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE);
    state = logic->GetState();
    EXPECT_EQ(state.overflow, OverflowEnum::kUnknownEnumValue);
    EXPECT_FALSE(HasAttributeChanges(mockContext.GetDirtyList(), Attributes::Overflow::Id));
}

//=========================================================================================
// Tests for command parameters
//=========================================================================================

using namespace Protocols::InteractionModel;

// This test ensures Handle set Target command executes as expected.
TEST_F(TestClosureDimensionClusterLogic, TestHandleSetTargetCommand)
{

    conformance.FeatureMap().Set(Feature::kPositioning).Set(Feature::kMotionLatching).Set(Feature::kSpeed);

    EXPECT_EQ(logic->Init(conformance, initParams), CHIP_NO_ERROR);
    mockContext.ClearDirtyList();

    DataModel::Nullable<GenericDimensionStateStruct> currentState;
    DataModel::Nullable<GenericDimensionStateStruct> target;
    GenericDimensionStateStruct testTargetStruct{ Optional<Percent100ths>(0), Optional<bool>(false),
                                                  Optional<Globals::ThreeLevelAutoEnum>(Globals::ThreeLevelAutoEnum::kAuto) };
    DataModel::Nullable<GenericDimensionStateStruct> testTarget(testTargetStruct);
    EXPECT_EQ(logic->SetTargetState(testTarget), CHIP_NO_ERROR);
    // Validating SetTargetState with no arguments
    mockContext.ClearDirtyList();
    EXPECT_EQ(logic->HandleSetTargetCommand(NullOptional, NullOptional, NullOptional), Status::InvalidCommand);
    EXPECT_FALSE(HasAttributeChanges(mockContext.GetDirtyList(), Attributes::CurrentState::Id));
    EXPECT_FALSE(HasAttributeChanges(mockContext.GetDirtyList(), Attributes::TargetState::Id));

    // Validating SetTargetState with invalid position
    mockContext.ClearDirtyList();
    EXPECT_EQ(logic->HandleSetTargetCommand(Optional<Percent100ths>(10001), NullOptional, NullOptional), Status::ConstraintError);
    EXPECT_FALSE(HasAttributeChanges(mockContext.GetDirtyList(), Attributes::CurrentState::Id));
    EXPECT_FALSE(HasAttributeChanges(mockContext.GetDirtyList(), Attributes::TargetState::Id));

    // Validating SetTargetState with manual latch
    BitFlags<LatchControlModesBitmap> latchControlModes;
    EXPECT_EQ(logic->SetLatchControlModes(latchControlModes), CHIP_NO_ERROR);
    mockContext.ClearDirtyList();
    EXPECT_EQ(logic->HandleSetTargetCommand(NullOptional, Optional<bool>(true), NullOptional), Status::InvalidInState);
    EXPECT_FALSE(HasAttributeChanges(mockContext.GetDirtyList(), Attributes::CurrentState::Id));
    EXPECT_FALSE(HasAttributeChanges(mockContext.GetDirtyList(), Attributes::TargetState::Id));
    mockContext.ClearDirtyList();
    EXPECT_EQ(logic->HandleSetTargetCommand(NullOptional, Optional<bool>(false), NullOptional), Status::InvalidInState);
    EXPECT_FALSE(HasAttributeChanges(mockContext.GetDirtyList(), Attributes::CurrentState::Id));
    EXPECT_FALSE(HasAttributeChanges(mockContext.GetDirtyList(), Attributes::TargetState::Id));
    latchControlModes.Set(ClosureDimension::LatchControlModesBitmap::kRemoteLatching)
        .Set(ClosureDimension::LatchControlModesBitmap::kRemoteUnlatching);
    EXPECT_EQ(logic->SetLatchControlModes(latchControlModes), CHIP_NO_ERROR);

    // Validating SetTargetState with invalid speed
    mockContext.ClearDirtyList();
    EXPECT_EQ(logic->HandleSetTargetCommand(NullOptional, NullOptional,
                                            Optional<Globals::ThreeLevelAutoEnum>(Globals::ThreeLevelAutoEnum::kUnknownEnumValue)),
              Status::ConstraintError);
    EXPECT_FALSE(HasAttributeChanges(mockContext.GetDirtyList(), Attributes::CurrentState::Id));
    EXPECT_FALSE(HasAttributeChanges(mockContext.GetDirtyList(), Attributes::TargetState::Id));

    // Validating SetTargetState with unknown current state
    mockContext.ClearDirtyList();
    EXPECT_EQ(logic->GetCurrentState(currentState), CHIP_NO_ERROR);
    EXPECT_EQ(currentState, DataModel::NullNullable);
    EXPECT_EQ(logic->HandleSetTargetCommand(Optional<Percent100ths>(1000), Optional<bool>(true),
                                            Optional<Globals::ThreeLevelAutoEnum>(Globals::ThreeLevelAutoEnum::kHigh)),
              Status::InvalidInState);
    EXPECT_FALSE(HasAttributeChanges(mockContext.GetDirtyList(), Attributes::CurrentState::Id));
    EXPECT_FALSE(HasAttributeChanges(mockContext.GetDirtyList(), Attributes::TargetState::Id));

    // Validating SetTargetState with proper arguments
    GenericDimensionStateStruct setCurrentStateStruct(Optional<Percent100ths>(0), Optional<bool>(false),
                                                      Optional<Globals::ThreeLevelAutoEnum>(Globals::ThreeLevelAutoEnum::kAuto));
    currentState.SetNonNull(setCurrentStateStruct);
    EXPECT_EQ(logic->SetCurrentState(currentState), CHIP_NO_ERROR);
    mockContext.ClearDirtyList();
    EXPECT_EQ(logic->HandleSetTargetCommand(Optional<Percent100ths>(1000), Optional<bool>(true),
                                            Optional<Globals::ThreeLevelAutoEnum>(Globals::ThreeLevelAutoEnum::kHigh)),
              Status::Success);
    EXPECT_EQ(logic->GetTargetState(target), CHIP_NO_ERROR);
    EXPECT_EQ(target.Value().position.Value().Value(), 1000);
    EXPECT_EQ(target.Value().latch.Value().Value(), true);
    EXPECT_EQ(target.Value().speed.Value(), Globals::ThreeLevelAutoEnum::kHigh);
    EXPECT_FALSE(HasAttributeChanges(mockContext.GetDirtyList(), Attributes::CurrentState::Id));
    EXPECT_TRUE(HasAttributeChanges(mockContext.GetDirtyList(), Attributes::TargetState::Id));

    // Validating SetTargetState with only position arguments
    mockContext.ClearDirtyList();
    EXPECT_EQ(logic->HandleSetTargetCommand(Optional<Percent100ths>(10000), NullOptional, NullOptional), Status::Success);
    EXPECT_EQ(logic->GetTargetState(target), CHIP_NO_ERROR);
    EXPECT_EQ(target.Value().position.Value().Value(), 10000);
    EXPECT_EQ(target.Value().latch.HasValue(), true);
    EXPECT_EQ(target.Value().speed.HasValue(), true);
    EXPECT_FALSE(HasAttributeChanges(mockContext.GetDirtyList(), Attributes::CurrentState::Id));
    EXPECT_TRUE(HasAttributeChanges(mockContext.GetDirtyList(), Attributes::TargetState::Id));
}

// This test ensures Handle set Target command executes as expected.
TEST_F(TestClosureDimensionClusterLogic, TestHandleSetTargetCommandWithLimitation)
{

    conformance.FeatureMap()
        .Set(Feature::kPositioning)
        .Set(Feature::kMotionLatching)
        .Set(Feature::kSpeed)
        .Set(Feature::kLimitation);

    EXPECT_EQ(logic->Init(conformance, initParams), CHIP_NO_ERROR);
    BitFlags<LatchControlModesBitmap> latchControlModes;
    latchControlModes.Set(ClosureDimension::LatchControlModesBitmap::kRemoteLatching)
        .Set(ClosureDimension::LatchControlModesBitmap::kRemoteUnlatching);
    EXPECT_EQ(logic->SetLatchControlModes(latchControlModes), CHIP_NO_ERROR);
    mockContext.ClearDirtyList();

    DataModel::Nullable<GenericDimensionStateStruct> currentState;
    DataModel::Nullable<GenericDimensionStateStruct> target;
    GenericDimensionStateStruct testTargetStruct{ Optional<Percent100ths>(0), Optional<bool>(false),
                                                  Optional<Globals::ThreeLevelAutoEnum>(Globals::ThreeLevelAutoEnum::kAuto) };
    DataModel::Nullable<GenericDimensionStateStruct> testTarget(testTargetStruct);

    EXPECT_EQ(logic->SetTargetState(testTarget), CHIP_NO_ERROR);
    Structs::RangePercent100thsStruct::Type limitRange = { .min = 1000, .max = 9000 };
    EXPECT_EQ(logic->SetLimitRange(limitRange), CHIP_NO_ERROR);

    // Validating SetTargetState with position greater than Limit.Max
    GenericDimensionStateStruct setCurrentStateStruct(Optional<Percent100ths>(1000), Optional<bool>(false),
                                                      Optional<Globals::ThreeLevelAutoEnum>(Globals::ThreeLevelAutoEnum::kAuto));
    currentState.SetNonNull(setCurrentStateStruct);
    EXPECT_EQ(logic->SetCurrentState(currentState), CHIP_NO_ERROR);
    mockContext.ClearDirtyList();
    EXPECT_EQ(logic->HandleSetTargetCommand(Optional<Percent100ths>(10000), Optional<bool>(true),
                                            Optional<Globals::ThreeLevelAutoEnum>(Globals::ThreeLevelAutoEnum::kHigh)),
              Status::Success);
    EXPECT_EQ(logic->GetTargetState(target), CHIP_NO_ERROR);
    EXPECT_EQ(target.Value().position.Value().Value(), 9000);
    EXPECT_EQ(target.Value().latch.Value().Value(), true);
    EXPECT_EQ(target.Value().speed.Value(), Globals::ThreeLevelAutoEnum::kHigh);
    EXPECT_FALSE(HasAttributeChanges(mockContext.GetDirtyList(), Attributes::CurrentState::Id));
    EXPECT_TRUE(HasAttributeChanges(mockContext.GetDirtyList(), Attributes::TargetState::Id));

    // Validating SetTargetState with position less the limit.Min
    setCurrentStateStruct.Set(Optional<Percent100ths>(9000), Optional<bool>(false),
                              Optional<Globals::ThreeLevelAutoEnum>(Globals::ThreeLevelAutoEnum::kAuto));
    currentState.SetNonNull(setCurrentStateStruct);
    EXPECT_EQ(logic->SetCurrentState(currentState), CHIP_NO_ERROR);
    mockContext.ClearDirtyList();
    EXPECT_EQ(logic->HandleSetTargetCommand(Optional<Percent100ths>(0), Optional<bool>(true),
                                            Optional<Globals::ThreeLevelAutoEnum>(Globals::ThreeLevelAutoEnum::kHigh)),
              Status::Success);
    EXPECT_EQ(logic->GetTargetState(target), CHIP_NO_ERROR);
    EXPECT_EQ(target.Value().position.Value().Value(), 1000);
    EXPECT_EQ(target.Value().latch.Value().Value(), true);
    EXPECT_EQ(target.Value().speed.Value(), Globals::ThreeLevelAutoEnum::kHigh);
    EXPECT_FALSE(HasAttributeChanges(mockContext.GetDirtyList(), Attributes::CurrentState::Id));
    EXPECT_TRUE(HasAttributeChanges(mockContext.GetDirtyList(), Attributes::TargetState::Id));
}

// HandleSetTarget command should return InvalidInState when CurrentState is latched and SetTarget command changes position without
// latch.
TEST_F(TestClosureDimensionClusterLogic, TestHandleSetTargetCommand_ChangePositionWithoutIncomingLatchWhenLatched)
{
    conformance.FeatureMap().Set(Feature::kPositioning).Set(Feature::kMotionLatching).Set(Feature::kSpeed);

    EXPECT_EQ(logic->Init(conformance, initParams), CHIP_NO_ERROR);
    mockContext.ClearDirtyList();

    DataModel::Nullable<GenericDimensionStateStruct> currentState;
    GenericDimensionStateStruct setCurrentStateStruct(Optional<Percent100ths>(1000), Optional<bool>(true),
                                                      Optional<Globals::ThreeLevelAutoEnum>(Globals::ThreeLevelAutoEnum::kAuto));
    currentState.SetNonNull(setCurrentStateStruct);
    EXPECT_EQ(logic->SetCurrentState(currentState), CHIP_NO_ERROR);
    EXPECT_EQ(logic->HandleSetTargetCommand(Optional<Percent100ths>(1000), NullOptional, NullOptional), Status::InvalidInState);
}

// HandleSetTarget command should return InvalidInState when CurrentState is latched and position is changed.
TEST_F(TestClosureDimensionClusterLogic, TestHandleSetTargetCommand_ChangePositionWhenLatched)
{

    conformance.FeatureMap().Set(Feature::kPositioning).Set(Feature::kMotionLatching).Set(Feature::kSpeed);

    EXPECT_EQ(logic->Init(conformance, initParams), CHIP_NO_ERROR);
    mockContext.ClearDirtyList();

    DataModel::Nullable<GenericDimensionStateStruct> currentState;
    GenericDimensionStateStruct setCurrentStateStruct(Optional<Percent100ths>(1000), Optional<bool>(true),
                                                      Optional<Globals::ThreeLevelAutoEnum>(Globals::ThreeLevelAutoEnum::kAuto));
    currentState.SetNonNull(setCurrentStateStruct);
    EXPECT_EQ(logic->SetCurrentState(currentState), CHIP_NO_ERROR);
    EXPECT_EQ(logic->HandleSetTargetCommand(Optional<Percent100ths>(1000), Optional<bool>(true), NullOptional),
              Status::InvalidInState);
}

// HandleSetTarget command should return Success when only LT feature is enabled and latch is changed.
TEST_F(TestClosureDimensionClusterLogic, TestHandleSetTargetCommand_ChangeLatchWhenOnlyLatchFeatureEnabled)
{

    conformance.FeatureMap().Set(Feature::kMotionLatching);

    EXPECT_EQ(logic->Init(conformance, initParams), CHIP_NO_ERROR);
    mockContext.ClearDirtyList();

    DataModel::Nullable<GenericDimensionStateStruct> currentState;
    GenericDimensionStateStruct setCurrentStateStruct(NullOptional, Optional<bool>(true), NullOptional);
    currentState.SetNonNull(setCurrentStateStruct);
    EXPECT_EQ(logic->SetCurrentState(currentState), CHIP_NO_ERROR);

    BitFlags<LatchControlModesBitmap> latchControlModes;
    latchControlModes.Set(ClosureDimension::LatchControlModesBitmap::kRemoteLatching)
        .Set(ClosureDimension::LatchControlModesBitmap::kRemoteUnlatching);
    EXPECT_EQ(logic->SetLatchControlModes(latchControlModes), CHIP_NO_ERROR);
    EXPECT_EQ(logic->HandleSetTargetCommand(NullOptional, Optional<bool>(false), NullOptional), Status::Success);
    DataModel::Nullable<GenericDimensionStateStruct> target;
    EXPECT_EQ(logic->GetTargetState(target), CHIP_NO_ERROR);
    EXPECT_EQ(target.Value().latch.Value(), false);
}

// HandleSetTarget command should return Success when CurrentState is latched and only speed is changed.
TEST_F(TestClosureDimensionClusterLogic, TestHandleSetTargetCommand_ChangeSpeedWhenLatched)
{

    conformance.FeatureMap().Set(Feature::kPositioning).Set(Feature::kMotionLatching).Set(Feature::kSpeed);

    EXPECT_EQ(logic->Init(conformance, initParams), CHIP_NO_ERROR);
    mockContext.ClearDirtyList();

    DataModel::Nullable<GenericDimensionStateStruct> currentState;
    GenericDimensionStateStruct setCurrentStateStruct(Optional<Percent100ths>(1000), Optional<bool>(true),
                                                      Optional<Globals::ThreeLevelAutoEnum>(Globals::ThreeLevelAutoEnum::kAuto));
    currentState.SetNonNull(setCurrentStateStruct);
    EXPECT_EQ(logic->SetCurrentState(currentState), CHIP_NO_ERROR);
    EXPECT_EQ(logic->HandleSetTargetCommand(NullOptional, NullOptional, Optional(Globals::ThreeLevelAutoEnum::kHigh)),
              Status::Success);
    DataModel::Nullable<GenericDimensionStateStruct> target;
    EXPECT_EQ(logic->GetTargetState(target), CHIP_NO_ERROR);
    EXPECT_FALSE(target.IsNull());
    EXPECT_EQ(target.Value().speed.Value(), Globals::ThreeLevelAutoEnum::kHigh);
}

// HandleSetTarget command should return Success when CurrentState is latched and only latch is changed.
TEST_F(TestClosureDimensionClusterLogic, TestHandleSetTargetCommand_ChangeLatchWhenLatched)
{

    conformance.FeatureMap().Set(Feature::kPositioning).Set(Feature::kMotionLatching).Set(Feature::kSpeed);
    BitFlags<LatchControlModesBitmap> latchControlModes;
    latchControlModes.Set(ClosureDimension::LatchControlModesBitmap::kRemoteLatching)
        .Set(ClosureDimension::LatchControlModesBitmap::kRemoteUnlatching);
    EXPECT_EQ(logic->Init(conformance, initParams), CHIP_NO_ERROR);
    EXPECT_EQ(logic->SetLatchControlModes(latchControlModes), CHIP_NO_ERROR);

    mockContext.ClearDirtyList();

    DataModel::Nullable<GenericDimensionStateStruct> currentState;
    GenericDimensionStateStruct setCurrentStateStruct(Optional<Percent100ths>(1000), Optional<bool>(true),
                                                      Optional<Globals::ThreeLevelAutoEnum>(Globals::ThreeLevelAutoEnum::kAuto));
    currentState.SetNonNull(setCurrentStateStruct);
    EXPECT_EQ(logic->SetCurrentState(currentState), CHIP_NO_ERROR);
    EXPECT_EQ(logic->HandleSetTargetCommand(NullOptional, Optional<bool>(false), NullOptional), Status::Success);
    DataModel::Nullable<GenericDimensionStateStruct> target;
    EXPECT_EQ(logic->GetTargetState(target), CHIP_NO_ERROR);
    EXPECT_FALSE(target.IsNull());
    EXPECT_EQ(target.Value().latch.Value(), false);
}

// This test ensures Handle Step command executes as expected. Tests:
// - Return InvalidInState if CurrentState is unknown.
// - Return constrainError if arguments value are out of bounds
TEST_F(TestClosureDimensionClusterLogic, TestHandleStepCommand)
{
    conformance.FeatureMap().Set(Feature::kPositioning).Set(Feature::kMotionLatching).Set(Feature::kSpeed);

    EXPECT_EQ(logic->Init(conformance, initParams), CHIP_NO_ERROR);
    mockContext.ClearDirtyList();

    DataModel::Nullable<GenericDimensionStateStruct> currentState;
    DataModel::Nullable<GenericDimensionStateStruct> target;

    GenericDimensionStateStruct testTargetStruct{ Optional<Percent100ths>(0), Optional<bool>(false),
                                                  Optional<Globals::ThreeLevelAutoEnum>(Globals::ThreeLevelAutoEnum::kAuto) };
    DataModel::Nullable<GenericDimensionStateStruct> testTarget(testTargetStruct);
    EXPECT_EQ(logic->SetTargetState(testTarget), CHIP_NO_ERROR);

    // Validating Step with Invalid direction
    mockContext.ClearDirtyList();
    EXPECT_EQ(logic->HandleStepCommand(StepDirectionEnum::kUnknownEnumValue, 1, NullOptional), Status::ConstraintError);
    EXPECT_FALSE(HasAttributeChanges(mockContext.GetDirtyList(), Attributes::CurrentState::Id));
    EXPECT_FALSE(HasAttributeChanges(mockContext.GetDirtyList(), Attributes::TargetState::Id));

    // Validating Step with invalid steps
    mockContext.ClearDirtyList();
    EXPECT_EQ(logic->HandleStepCommand(StepDirectionEnum::kDecrease, 0, NullOptional), Status::ConstraintError);
    EXPECT_FALSE(HasAttributeChanges(mockContext.GetDirtyList(), Attributes::CurrentState::Id));
    EXPECT_FALSE(HasAttributeChanges(mockContext.GetDirtyList(), Attributes::TargetState::Id));

    // Validating Step with invalid speed
    mockContext.ClearDirtyList();
    EXPECT_EQ(logic->HandleStepCommand(StepDirectionEnum::kDecrease, 1,
                                       Optional<Globals::ThreeLevelAutoEnum>(Globals::ThreeLevelAutoEnum::kUnknownEnumValue)),
              Status::ConstraintError);
    EXPECT_FALSE(HasAttributeChanges(mockContext.GetDirtyList(), Attributes::CurrentState::Id));
    EXPECT_FALSE(HasAttributeChanges(mockContext.GetDirtyList(), Attributes::TargetState::Id));

    // Validating Step with unknown current state
    mockContext.ClearDirtyList();
    EXPECT_EQ(logic->GetCurrentState(currentState), CHIP_NO_ERROR);
    EXPECT_EQ(currentState, DataModel::NullNullable);
    EXPECT_EQ(logic->HandleStepCommand(StepDirectionEnum::kIncrease, 1,
                                       Optional<Globals::ThreeLevelAutoEnum>(Globals::ThreeLevelAutoEnum::kHigh)),
              Status::InvalidInState);
    EXPECT_FALSE(HasAttributeChanges(mockContext.GetDirtyList(), Attributes::CurrentState::Id));
    EXPECT_FALSE(HasAttributeChanges(mockContext.GetDirtyList(), Attributes::TargetState::Id));

    Percent100ths stepValue = 10;
    EXPECT_EQ(logic->SetStepValue(stepValue), CHIP_NO_ERROR);

    // Validating Step increase with proper arguments
    GenericDimensionStateStruct setCurrentStateStruct(Optional<Percent100ths>(0), Optional<bool>(false),
                                                      Optional<Globals::ThreeLevelAutoEnum>(Globals::ThreeLevelAutoEnum::kAuto));
    currentState.SetNonNull(setCurrentStateStruct);
    EXPECT_EQ(logic->SetCurrentState(currentState), CHIP_NO_ERROR);
    mockContext.ClearDirtyList();
    EXPECT_EQ(logic->HandleStepCommand(StepDirectionEnum::kIncrease, 10,
                                       Optional<Globals::ThreeLevelAutoEnum>(Globals::ThreeLevelAutoEnum::kHigh)),
              Protocols::InteractionModel::Status::Success);
    EXPECT_EQ(logic->GetTargetState(target), CHIP_NO_ERROR);
    EXPECT_EQ(target.Value().position.Value(), static_cast<unsigned short>(100));
    EXPECT_EQ(target.Value().latch.HasValue(), true);
    EXPECT_EQ(target.Value().speed.Value(), Globals::ThreeLevelAutoEnum::kHigh);
    EXPECT_TRUE(HasAttributeChanges(mockContext.GetDirtyList(), Attributes::TargetState::Id));
    // As delegate is not implemented, we are updating current state here
    setCurrentStateStruct.Set(Optional<Percent100ths>(100), Optional<bool>(false),
                              Optional<Globals::ThreeLevelAutoEnum>(Globals::ThreeLevelAutoEnum::kAuto));
    currentState.SetNonNull(setCurrentStateStruct);
    EXPECT_EQ(logic->SetCurrentState(currentState), CHIP_NO_ERROR);

    // Validating Step increase which target will be >10000
    mockContext.ClearDirtyList();
    EXPECT_EQ(logic->HandleStepCommand(StepDirectionEnum::kIncrease, 65535,
                                       Optional<Globals::ThreeLevelAutoEnum>(Globals::ThreeLevelAutoEnum::kMedium)),
              Protocols::InteractionModel::Status::Success);
    EXPECT_EQ(logic->GetTargetState(target), CHIP_NO_ERROR);
    EXPECT_EQ(target.Value().position.Value(), static_cast<unsigned short>(10000));
    EXPECT_EQ(target.Value().latch.HasValue(), true);
    EXPECT_EQ(target.Value().speed.Value(), Globals::ThreeLevelAutoEnum::kMedium);
    EXPECT_TRUE(HasAttributeChanges(mockContext.GetDirtyList(), Attributes::TargetState::Id));
    // As delegate is not implemented, we are updating current state here
    setCurrentStateStruct.Set(Optional<Percent100ths>(10000), Optional<bool>(false),
                              Optional<Globals::ThreeLevelAutoEnum>(Globals::ThreeLevelAutoEnum::kAuto));
    currentState.SetNonNull(setCurrentStateStruct);
    EXPECT_EQ(logic->SetCurrentState(currentState), CHIP_NO_ERROR);

    // Validating Step decrease
    mockContext.ClearDirtyList();
    EXPECT_EQ(logic->HandleStepCommand(StepDirectionEnum::kDecrease, 10,
                                       Optional<Globals::ThreeLevelAutoEnum>(Globals::ThreeLevelAutoEnum::kLow)),
              Protocols::InteractionModel::Status::Success);
    EXPECT_EQ(logic->GetTargetState(target), CHIP_NO_ERROR);
    EXPECT_EQ(target.Value().position.Value(), static_cast<unsigned short>(9900));
    EXPECT_EQ(target.Value().latch.HasValue(), true);
    EXPECT_EQ(target.Value().speed.Value(), Globals::ThreeLevelAutoEnum::kLow);
    EXPECT_TRUE(HasAttributeChanges(mockContext.GetDirtyList(), Attributes::TargetState::Id));
    // As delegate is not implemented, we are updating current state here
    setCurrentStateStruct.Set(Optional<Percent100ths>(9900), Optional<bool>(false),
                              Optional<Globals::ThreeLevelAutoEnum>(Globals::ThreeLevelAutoEnum::kAuto));
    currentState.SetNonNull(setCurrentStateStruct);
    EXPECT_EQ(logic->SetCurrentState(currentState), CHIP_NO_ERROR);

    // Validating Step decrease which target will be <0
    mockContext.ClearDirtyList();
    EXPECT_EQ(logic->HandleStepCommand(StepDirectionEnum::kDecrease, 65535,
                                       Optional<Globals::ThreeLevelAutoEnum>(Globals::ThreeLevelAutoEnum::kAuto)),
              Protocols::InteractionModel::Status::Success);
    EXPECT_EQ(logic->GetTargetState(target), CHIP_NO_ERROR);
    EXPECT_EQ(target.Value().position.Value(), static_cast<unsigned short>(0));
    EXPECT_EQ(target.Value().latch.HasValue(), true);
    EXPECT_EQ(target.Value().speed.Value(), Globals::ThreeLevelAutoEnum::kAuto);
    EXPECT_TRUE(HasAttributeChanges(mockContext.GetDirtyList(), Attributes::TargetState::Id));
    // As delegate is not implemented, we are updating current state here
    setCurrentStateStruct.Set(Optional<Percent100ths>(0), Optional<bool>(false),
                              Optional<Globals::ThreeLevelAutoEnum>(Globals::ThreeLevelAutoEnum::kAuto));
    currentState.SetNonNull(setCurrentStateStruct);
    EXPECT_EQ(logic->SetCurrentState(currentState), CHIP_NO_ERROR);
}

// This test ensures Handle Step command executes as expected. Tests:
// - Return InvalidInState if CurrentState is unknown.
// - Return constrainError if arguments value are out of bounds
TEST_F(TestClosureDimensionClusterLogic, TestHandleStepCommandWithLimitation)
{
    conformance.FeatureMap()
        .Set(Feature::kPositioning)
        .Set(Feature::kMotionLatching)
        .Set(Feature::kSpeed)
        .Set(Feature::kLimitation);

    EXPECT_EQ(logic->Init(conformance, initParams), CHIP_NO_ERROR);
    mockContext.ClearDirtyList();

    DataModel::Nullable<GenericDimensionStateStruct> currentState;
    DataModel::Nullable<GenericDimensionStateStruct> target;
    GenericDimensionStateStruct testTargetStruct{ Optional<Percent100ths>(0), Optional<bool>(false),
                                                  Optional<Globals::ThreeLevelAutoEnum>(Globals::ThreeLevelAutoEnum::kAuto) };
    DataModel::Nullable<GenericDimensionStateStruct> testTarget(testTargetStruct);

    EXPECT_EQ(logic->SetTargetState(testTarget), CHIP_NO_ERROR);

    Percent100ths stepValue = 10;
    EXPECT_EQ(logic->SetStepValue(stepValue), CHIP_NO_ERROR);

    // Validating Step with proper arguments
    GenericDimensionStateStruct setCurrentStateStruct(Optional<Percent100ths>(1000), Optional<bool>(false),
                                                      Optional<Globals::ThreeLevelAutoEnum>(Globals::ThreeLevelAutoEnum::kAuto));
    currentState.SetNonNull(setCurrentStateStruct);
    EXPECT_EQ(logic->SetCurrentState(currentState), CHIP_NO_ERROR);
    Structs::RangePercent100thsStruct::Type limitRange = { .min = 1000, .max = 9000 };
    EXPECT_EQ(logic->SetLimitRange(limitRange), CHIP_NO_ERROR);

    mockContext.ClearDirtyList();
    EXPECT_EQ(logic->HandleStepCommand(StepDirectionEnum::kIncrease, 10,
                                       Optional<Globals::ThreeLevelAutoEnum>(Globals::ThreeLevelAutoEnum::kLow)),
              Protocols::InteractionModel::Status::Success);
    EXPECT_EQ(logic->GetTargetState(target), CHIP_NO_ERROR);
    EXPECT_EQ(target.Value().position.Value(), static_cast<unsigned short>(1100));
    EXPECT_EQ(target.Value().latch.HasValue(), true);
    EXPECT_EQ(target.Value().speed.Value(), Globals::ThreeLevelAutoEnum::kLow);
    EXPECT_TRUE(HasAttributeChanges(mockContext.GetDirtyList(), Attributes::TargetState::Id));
    // As delegate is not implemented, we are updating current state here
    setCurrentStateStruct.Set(Optional<Percent100ths>(1100), Optional<bool>(false),
                              Optional<Globals::ThreeLevelAutoEnum>(Globals::ThreeLevelAutoEnum::kAuto));
    currentState.SetNonNull(setCurrentStateStruct);
    EXPECT_EQ(logic->SetCurrentState(currentState), CHIP_NO_ERROR);

    mockContext.ClearDirtyList();
    EXPECT_EQ(logic->HandleStepCommand(StepDirectionEnum::kIncrease, 65535,
                                       Optional<Globals::ThreeLevelAutoEnum>(Globals::ThreeLevelAutoEnum::kMedium)),
              Protocols::InteractionModel::Status::Success);
    EXPECT_EQ(logic->GetTargetState(target), CHIP_NO_ERROR);
    EXPECT_EQ(target.Value().position.Value(), static_cast<unsigned short>(9000));
    EXPECT_EQ(target.Value().latch.HasValue(), true);
    EXPECT_EQ(target.Value().speed.Value(), Globals::ThreeLevelAutoEnum::kMedium);
    EXPECT_TRUE(HasAttributeChanges(mockContext.GetDirtyList(), Attributes::TargetState::Id));
    // As delegate is not implemented, we are updating current state here
    setCurrentStateStruct.Set(Optional<Percent100ths>(9000), Optional<bool>(false),
                              Optional<Globals::ThreeLevelAutoEnum>(Globals::ThreeLevelAutoEnum::kAuto));
    currentState.SetNonNull(setCurrentStateStruct);
    EXPECT_EQ(logic->SetCurrentState(currentState), CHIP_NO_ERROR);

    mockContext.ClearDirtyList();
    EXPECT_EQ(logic->HandleStepCommand(StepDirectionEnum::kDecrease, 10,
                                       Optional<Globals::ThreeLevelAutoEnum>(Globals::ThreeLevelAutoEnum::kLow)),
              Protocols::InteractionModel::Status::Success);
    EXPECT_EQ(logic->GetTargetState(target), CHIP_NO_ERROR);
    EXPECT_EQ(target.Value().position.Value(), static_cast<unsigned short>(8900));
    EXPECT_EQ(target.Value().latch.HasValue(), true);
    EXPECT_EQ(target.Value().speed.Value(), Globals::ThreeLevelAutoEnum::kLow);
    EXPECT_TRUE(HasAttributeChanges(mockContext.GetDirtyList(), Attributes::TargetState::Id));
    // As delegate is not implemented, we are updating current state here
    setCurrentStateStruct.Set(Optional<Percent100ths>(8900), Optional<bool>(false),
                              Optional<Globals::ThreeLevelAutoEnum>(Globals::ThreeLevelAutoEnum::kAuto));
    currentState.SetNonNull(setCurrentStateStruct);
    EXPECT_EQ(logic->SetCurrentState(currentState), CHIP_NO_ERROR);

    mockContext.ClearDirtyList();
    EXPECT_EQ(logic->HandleStepCommand(StepDirectionEnum::kDecrease, 65535,
                                       Optional<Globals::ThreeLevelAutoEnum>(Globals::ThreeLevelAutoEnum::kAuto)),
              Protocols::InteractionModel::Status::Success);
    EXPECT_EQ(logic->GetTargetState(target), CHIP_NO_ERROR);
    EXPECT_EQ(target.Value().position.Value(), static_cast<unsigned short>(1000));
    EXPECT_EQ(target.Value().latch.HasValue(), true);
    EXPECT_EQ(target.Value().speed.Value(), Globals::ThreeLevelAutoEnum::kAuto);
    EXPECT_TRUE(HasAttributeChanges(mockContext.GetDirtyList(), Attributes::TargetState::Id));
    // As delegate is not implemented, we are updating current state here
    setCurrentStateStruct.Set(Optional<Percent100ths>(1000), Optional<bool>(false),
                              Optional<Globals::ThreeLevelAutoEnum>(Globals::ThreeLevelAutoEnum::kAuto));
    currentState.SetNonNull(setCurrentStateStruct);
    EXPECT_EQ(logic->SetCurrentState(currentState), CHIP_NO_ERROR);
}

TEST_F(TestClosureDimensionClusterLogic, TestHandleStepCommandWhenLatched)
{
    conformance.FeatureMap()
        .Set(Feature::kPositioning)
        .Set(Feature::kMotionLatching)
        .Set(Feature::kSpeed)
        .Set(Feature::kLimitation);

    EXPECT_EQ(logic->Init(conformance, initParams), CHIP_NO_ERROR);
    mockContext.ClearDirtyList();

    DataModel::Nullable<GenericDimensionStateStruct> currentState;
    Percent100ths stepValue = 10;
    EXPECT_EQ(logic->SetStepValue(stepValue), CHIP_NO_ERROR);

    // Validating Step with proper arguments
    GenericDimensionStateStruct setCurrentStateStruct(Optional<Percent100ths>(1000), Optional<bool>(true),
                                                      Optional<Globals::ThreeLevelAutoEnum>(Globals::ThreeLevelAutoEnum::kAuto));
    currentState.SetNonNull(setCurrentStateStruct);
    EXPECT_EQ(logic->SetCurrentState(currentState), CHIP_NO_ERROR);
    Structs::RangePercent100thsStruct::Type limitRange = { .min = 1000, .max = 9000 };
    EXPECT_EQ(logic->SetLimitRange(limitRange), CHIP_NO_ERROR);

    mockContext.ClearDirtyList();
    EXPECT_EQ(logic->HandleStepCommand(StepDirectionEnum::kIncrease, 10,
                                       Optional<Globals::ThreeLevelAutoEnum>(Globals::ThreeLevelAutoEnum::kLow)),
              Protocols::InteractionModel::Status::InvalidInState);
}

//=========================================================================================
// Tests for CurrentState Attribute Quiet Reporting
//=========================================================================================

TEST_F(TestClosureDimensionClusterLogic, TestCurrentStateQuietReportingPositionNonNulltoNull)
{
    conformance.FeatureMap().Set(Feature::kPositioning).Set(Feature::kMotionLatching).Set(Feature::kSpeed);

    EXPECT_EQ(logic->Init(conformance, initParams), CHIP_NO_ERROR);
    mockContext.ClearDirtyList();

    GenericDimensionStateStruct testCurrentStateStruct;
    testCurrentStateStruct.position = Optional<DataModel::Nullable<chip::Percent100ths>>(1000);
    testCurrentStateStruct.latch    = Optional<DataModel::Nullable<bool>>(false);
    testCurrentStateStruct.speed    = Optional<Globals::ThreeLevelAutoEnum>(Globals::ThreeLevelAutoEnum::kLow);

    DataModel::Nullable<GenericDimensionStateStruct> testCurrentState(testCurrentStateStruct);
    DataModel::Nullable<GenericDimensionStateStruct> currentState;

    EXPECT_EQ(logic->GetCurrentState(currentState), CHIP_NO_ERROR);
    EXPECT_EQ(currentState, DataModel::NullNullable);

    mockContext.ClearDirtyList();

    // set position to 1000
    EXPECT_EQ(logic->SetCurrentState(testCurrentState), CHIP_NO_ERROR);
    EXPECT_EQ(logic->GetCurrentState(currentState), CHIP_NO_ERROR);
    EXPECT_EQ(currentState, testCurrentState);

    mockContext.ClearDirtyList();

    // set position to null
    testCurrentState.Value().position.Value().SetNull();
    EXPECT_EQ(logic->SetCurrentState(testCurrentState), CHIP_NO_ERROR);
    EXPECT_EQ(logic->GetCurrentState(currentState), CHIP_NO_ERROR);
    EXPECT_EQ(currentState, testCurrentState);
    EXPECT_TRUE(HasAttributeChanges(mockContext.GetDirtyList(), Attributes::CurrentState::Id));

    mockContext.ClearDirtyList();
}

TEST_F(TestClosureDimensionClusterLogic, TestCurrentStateQuietReportingPositionNulltoNonNull)
{
    conformance.FeatureMap().Set(Feature::kPositioning).Set(Feature::kMotionLatching).Set(Feature::kSpeed);

    EXPECT_EQ(logic->Init(conformance, initParams), CHIP_NO_ERROR);
    mockContext.ClearDirtyList();

    GenericDimensionStateStruct testCurrentStateStruct;
    testCurrentStateStruct.position = Optional<DataModel::Nullable<chip::Percent100ths>>(DataModel::NullNullable);
    testCurrentStateStruct.latch    = Optional<DataModel::Nullable<bool>>(false);
    testCurrentStateStruct.speed    = Optional<Globals::ThreeLevelAutoEnum>(Globals::ThreeLevelAutoEnum::kLow);

    DataModel::Nullable<GenericDimensionStateStruct> testCurrentState(testCurrentStateStruct);
    DataModel::Nullable<GenericDimensionStateStruct> currentState;

    EXPECT_EQ(logic->GetCurrentState(currentState), CHIP_NO_ERROR);
    EXPECT_EQ(currentState, DataModel::NullNullable);

    mockContext.ClearDirtyList();

    // set position as null
    EXPECT_EQ(logic->SetCurrentState(testCurrentState), CHIP_NO_ERROR);
    EXPECT_EQ(logic->GetCurrentState(currentState), CHIP_NO_ERROR);
    EXPECT_EQ(currentState, testCurrentState);

    mockContext.ClearDirtyList();

    // set position to NonNull(1000)
    testCurrentState.Value().position.SetValue(DataModel::MakeNullable<chip::Percent100ths>(chip::Percent100ths(1000)));
    EXPECT_EQ(logic->SetCurrentState(testCurrentState), CHIP_NO_ERROR);
    EXPECT_EQ(logic->GetCurrentState(currentState), CHIP_NO_ERROR);
    EXPECT_EQ(currentState, testCurrentState);
    EXPECT_TRUE(HasAttributeChanges(mockContext.GetDirtyList(), Attributes::CurrentState::Id));

    mockContext.ClearDirtyList();
}

TEST_F(TestClosureDimensionClusterLogic, TestCurrentStateQuietReportingPositionChangeValueWithoutDelay)
{
    conformance.FeatureMap().Set(Feature::kPositioning).Set(Feature::kMotionLatching).Set(Feature::kSpeed);

    EXPECT_EQ(logic->Init(conformance, initParams), CHIP_NO_ERROR);
    mockContext.ClearDirtyList();

    GenericDimensionStateStruct testCurrentStateStruct;
    testCurrentStateStruct.position = Optional<DataModel::Nullable<chip::Percent100ths>>(1000);
    testCurrentStateStruct.latch    = Optional<DataModel::Nullable<bool>>(false);
    testCurrentStateStruct.speed    = Optional<Globals::ThreeLevelAutoEnum>(Globals::ThreeLevelAutoEnum::kLow);

    DataModel::Nullable<GenericDimensionStateStruct> testCurrentState(testCurrentStateStruct);
    DataModel::Nullable<GenericDimensionStateStruct> currentState;

    EXPECT_EQ(logic->GetCurrentState(currentState), CHIP_NO_ERROR);
    EXPECT_EQ(currentState, DataModel::NullNullable);

    mockContext.ClearDirtyList();

    // set position as 1000
    EXPECT_EQ(logic->SetCurrentState(testCurrentState), CHIP_NO_ERROR);
    EXPECT_EQ(logic->GetCurrentState(currentState), CHIP_NO_ERROR);
    EXPECT_EQ(currentState, testCurrentState);

    mockContext.ClearDirtyList();

    // set position to 2000
    testCurrentState.Value().position.SetValue(DataModel::MakeNullable<chip::Percent100ths>(chip::Percent100ths(2000)));
    EXPECT_EQ(logic->SetCurrentState(testCurrentState), CHIP_NO_ERROR);
    EXPECT_EQ(logic->GetCurrentState(currentState), CHIP_NO_ERROR);
    EXPECT_EQ(currentState, testCurrentState);
    EXPECT_FALSE(HasAttributeChanges(mockContext.GetDirtyList(), Attributes::CurrentState::Id));

    mockContext.ClearDirtyList();
}

TEST_F(TestClosureDimensionClusterLogic, TestCurrentStateQuietReportingPositionChangeValueWithDelay)
{
    conformance.FeatureMap().Set(Feature::kPositioning).Set(Feature::kMotionLatching).Set(Feature::kSpeed);

    EXPECT_EQ(logic->Init(conformance, initParams), CHIP_NO_ERROR);
    mockContext.ClearDirtyList();

    GenericDimensionStateStruct testCurrentStateStruct;
    testCurrentStateStruct.position = Optional<DataModel::Nullable<chip::Percent100ths>>(1000);
    testCurrentStateStruct.latch    = Optional<DataModel::Nullable<bool>>(false);
    testCurrentStateStruct.speed    = Optional<Globals::ThreeLevelAutoEnum>(Globals::ThreeLevelAutoEnum::kLow);

    DataModel::Nullable<GenericDimensionStateStruct> testCurrentState(testCurrentStateStruct);
    DataModel::Nullable<GenericDimensionStateStruct> currentState;

    EXPECT_EQ(logic->GetCurrentState(currentState), CHIP_NO_ERROR);
    EXPECT_EQ(currentState, DataModel::NullNullable);

    mockContext.ClearDirtyList();

    // set position as 1000
    EXPECT_EQ(logic->SetCurrentState(testCurrentState), CHIP_NO_ERROR);
    EXPECT_EQ(logic->GetCurrentState(currentState), CHIP_NO_ERROR);
    EXPECT_EQ(currentState, testCurrentState);

    mockContext.ClearDirtyList();

    chip::test_utils::SleepMillis(2000); // Sleep for 2 seconds

    // set position to 2000
    testCurrentState.Value().position.SetValue(DataModel::MakeNullable<chip::Percent100ths>(chip::Percent100ths(2000)));
    EXPECT_EQ(logic->SetCurrentState(testCurrentState), CHIP_NO_ERROR);
    EXPECT_EQ(logic->GetCurrentState(currentState), CHIP_NO_ERROR);
    EXPECT_EQ(currentState, testCurrentState);
    EXPECT_FALSE(HasAttributeChanges(mockContext.GetDirtyList(), Attributes::CurrentState::Id));

    mockContext.ClearDirtyList();

    chip::test_utils::SleepMillis(2000); // Sleep for 2 seconds

    // set position to 3000
    testCurrentState.Value().position.SetValue(DataModel::MakeNullable<chip::Percent100ths>(chip::Percent100ths(3000)));
    EXPECT_EQ(logic->SetCurrentState(testCurrentState), CHIP_NO_ERROR);
    EXPECT_EQ(logic->GetCurrentState(currentState), CHIP_NO_ERROR);
    EXPECT_EQ(currentState, testCurrentState);
    EXPECT_FALSE(HasAttributeChanges(mockContext.GetDirtyList(), Attributes::CurrentState::Id));

    mockContext.ClearDirtyList();

    chip::test_utils::SleepMillis(2000); // Sleep for 2 seconds

    // set position to 4000
    testCurrentState.Value().position.SetValue(DataModel::MakeNullable<chip::Percent100ths>(chip::Percent100ths(4000)));
    EXPECT_EQ(logic->SetCurrentState(testCurrentState), CHIP_NO_ERROR);
    EXPECT_EQ(logic->GetCurrentState(currentState), CHIP_NO_ERROR);
    EXPECT_EQ(currentState, testCurrentState);
    EXPECT_TRUE(HasAttributeChanges(mockContext.GetDirtyList(), Attributes::CurrentState::Id));

    mockContext.ClearDirtyList();
}

TEST_F(TestClosureDimensionClusterLogic, TestCurrentStateQuietReportingLatchNulltoValue)
{
    conformance.FeatureMap().Set(Feature::kPositioning).Set(Feature::kMotionLatching).Set(Feature::kSpeed);

    EXPECT_EQ(logic->Init(conformance, initParams), CHIP_NO_ERROR);
    mockContext.ClearDirtyList();

    GenericDimensionStateStruct testCurrentStateStruct;
    testCurrentStateStruct.position = Optional<DataModel::Nullable<chip::Percent100ths>>(1000);
    testCurrentStateStruct.latch    = Optional<DataModel::Nullable<bool>>(DataModel::NullNullable);
    testCurrentStateStruct.speed    = Optional<Globals::ThreeLevelAutoEnum>(Globals::ThreeLevelAutoEnum::kLow);

    DataModel::Nullable<GenericDimensionStateStruct> testCurrentState(testCurrentStateStruct);
    DataModel::Nullable<GenericDimensionStateStruct> currentState;

    EXPECT_EQ(logic->GetCurrentState(currentState), CHIP_NO_ERROR);
    EXPECT_EQ(currentState, DataModel::NullNullable);

    mockContext.ClearDirtyList();

    // set latch as null
    EXPECT_EQ(logic->SetCurrentState(testCurrentState), CHIP_NO_ERROR);
    EXPECT_EQ(logic->GetCurrentState(currentState), CHIP_NO_ERROR);
    EXPECT_EQ(currentState, testCurrentState);

    mockContext.ClearDirtyList();

    // set latch to false
    testCurrentState.Value().latch.SetValue(DataModel::MakeNullable<bool>(false));
    EXPECT_EQ(logic->SetCurrentState(testCurrentState), CHIP_NO_ERROR);
    EXPECT_EQ(logic->GetCurrentState(currentState), CHIP_NO_ERROR);
    EXPECT_EQ(currentState, testCurrentState);
    EXPECT_TRUE(HasAttributeChanges(mockContext.GetDirtyList(), Attributes::CurrentState::Id));

    mockContext.ClearDirtyList();
}

TEST_F(TestClosureDimensionClusterLogic, TestCurrentStateQuietReportingLatchValuetoNull)
{
    conformance.FeatureMap().Set(Feature::kPositioning).Set(Feature::kMotionLatching).Set(Feature::kSpeed);

    EXPECT_EQ(logic->Init(conformance, initParams), CHIP_NO_ERROR);
    mockContext.ClearDirtyList();

    GenericDimensionStateStruct testCurrentStateStruct;
    testCurrentStateStruct.position = Optional<DataModel::Nullable<chip::Percent100ths>>(1000);
    testCurrentStateStruct.latch    = Optional<DataModel::Nullable<bool>>(false);
    testCurrentStateStruct.speed    = Optional<Globals::ThreeLevelAutoEnum>(Globals::ThreeLevelAutoEnum::kLow);

    DataModel::Nullable<GenericDimensionStateStruct> testCurrentState(testCurrentStateStruct);
    DataModel::Nullable<GenericDimensionStateStruct> currentState;

    EXPECT_EQ(logic->GetCurrentState(currentState), CHIP_NO_ERROR);
    EXPECT_EQ(currentState, DataModel::NullNullable);

    mockContext.ClearDirtyList();

    // set latch as false
    EXPECT_EQ(logic->SetCurrentState(testCurrentState), CHIP_NO_ERROR);
    EXPECT_EQ(logic->GetCurrentState(currentState), CHIP_NO_ERROR);
    EXPECT_EQ(currentState, testCurrentState);

    mockContext.ClearDirtyList();

    // set latch to null
    testCurrentState.Value().latch.Value().SetNull();
    EXPECT_EQ(logic->SetCurrentState(testCurrentState), CHIP_NO_ERROR);
    EXPECT_EQ(logic->GetCurrentState(currentState), CHIP_NO_ERROR);
    EXPECT_EQ(currentState, testCurrentState);
    EXPECT_TRUE(HasAttributeChanges(mockContext.GetDirtyList(), Attributes::CurrentState::Id));

    mockContext.ClearDirtyList();
}

TEST_F(TestClosureDimensionClusterLogic, TestCurrentStateQuietReportingLatchValueChange)
{
    conformance.FeatureMap().Set(Feature::kPositioning).Set(Feature::kMotionLatching).Set(Feature::kSpeed);

    EXPECT_EQ(logic->Init(conformance, initParams), CHIP_NO_ERROR);
    mockContext.ClearDirtyList();

    GenericDimensionStateStruct testCurrentStateStruct;
    testCurrentStateStruct.position = Optional<DataModel::Nullable<chip::Percent100ths>>(1000);
    testCurrentStateStruct.latch    = Optional<DataModel::Nullable<bool>>(false);
    testCurrentStateStruct.speed    = Optional<Globals::ThreeLevelAutoEnum>(Globals::ThreeLevelAutoEnum::kLow);

    DataModel::Nullable<GenericDimensionStateStruct> testCurrentState(testCurrentStateStruct);
    DataModel::Nullable<GenericDimensionStateStruct> currentState;

    EXPECT_EQ(logic->GetCurrentState(currentState), CHIP_NO_ERROR);
    EXPECT_EQ(currentState, DataModel::NullNullable);

    mockContext.ClearDirtyList();

    // set latch as false
    EXPECT_EQ(logic->SetCurrentState(testCurrentState), CHIP_NO_ERROR);
    EXPECT_EQ(logic->GetCurrentState(currentState), CHIP_NO_ERROR);
    EXPECT_EQ(currentState, testCurrentState);

    mockContext.ClearDirtyList();

    // set latch to true
    testCurrentState.Value().latch.Value().SetNonNull(true);
    EXPECT_EQ(logic->SetCurrentState(testCurrentState), CHIP_NO_ERROR);
    EXPECT_EQ(logic->GetCurrentState(currentState), CHIP_NO_ERROR);
    EXPECT_EQ(currentState, testCurrentState);
    EXPECT_TRUE(HasAttributeChanges(mockContext.GetDirtyList(), Attributes::CurrentState::Id));

    mockContext.ClearDirtyList();
}

TEST_F(TestClosureDimensionClusterLogic, TestCurrentStateQuietReportingSpeedNullOptionaltoValue)
{
    conformance.FeatureMap().Set(Feature::kPositioning).Set(Feature::kMotionLatching).Set(Feature::kSpeed);

    EXPECT_EQ(logic->Init(conformance, initParams), CHIP_NO_ERROR);
    mockContext.ClearDirtyList();

    GenericDimensionStateStruct testCurrentStateStruct;
    testCurrentStateStruct.position = Optional<DataModel::Nullable<chip::Percent100ths>>(1000);
    testCurrentStateStruct.latch    = Optional<DataModel::Nullable<bool>>(false);
    testCurrentStateStruct.speed    = NullOptional;

    DataModel::Nullable<GenericDimensionStateStruct> testCurrentState(testCurrentStateStruct);
    DataModel::Nullable<GenericDimensionStateStruct> currentState;

    EXPECT_EQ(logic->GetCurrentState(currentState), CHIP_NO_ERROR);
    EXPECT_EQ(currentState, DataModel::NullNullable);

    mockContext.ClearDirtyList();

    // set speed as nulloptional
    EXPECT_EQ(logic->SetCurrentState(testCurrentState), CHIP_NO_ERROR);
    EXPECT_EQ(logic->GetCurrentState(currentState), CHIP_NO_ERROR);
    EXPECT_EQ(currentState, testCurrentState);

    mockContext.ClearDirtyList();

    // set speed to low
    testCurrentState.Value().speed.SetValue(Globals::ThreeLevelAutoEnum::kLow);
    EXPECT_EQ(logic->SetCurrentState(testCurrentState), CHIP_NO_ERROR);
    EXPECT_EQ(logic->GetCurrentState(currentState), CHIP_NO_ERROR);
    EXPECT_EQ(currentState, testCurrentState);
    EXPECT_TRUE(HasAttributeChanges(mockContext.GetDirtyList(), Attributes::CurrentState::Id));

    mockContext.ClearDirtyList();
}

TEST_F(TestClosureDimensionClusterLogic, TestCurrentStateQuietReportingSpeedValuetoNullOptional)
{
    conformance.FeatureMap().Set(Feature::kPositioning).Set(Feature::kMotionLatching).Set(Feature::kSpeed);

    EXPECT_EQ(logic->Init(conformance, initParams), CHIP_NO_ERROR);
    mockContext.ClearDirtyList();

    GenericDimensionStateStruct testCurrentStateStruct;
    testCurrentStateStruct.position = Optional<DataModel::Nullable<chip::Percent100ths>>(1000);
    testCurrentStateStruct.latch    = Optional<DataModel::Nullable<bool>>(false);
    testCurrentStateStruct.speed    = Optional<Globals::ThreeLevelAutoEnum>(Globals::ThreeLevelAutoEnum::kLow);

    DataModel::Nullable<GenericDimensionStateStruct> testCurrentState(testCurrentStateStruct);
    DataModel::Nullable<GenericDimensionStateStruct> currentState;

    EXPECT_EQ(logic->GetCurrentState(currentState), CHIP_NO_ERROR);
    EXPECT_EQ(currentState, DataModel::NullNullable);

    mockContext.ClearDirtyList();

    // set speed as low
    EXPECT_EQ(logic->SetCurrentState(testCurrentState), CHIP_NO_ERROR);
    EXPECT_EQ(logic->GetCurrentState(currentState), CHIP_NO_ERROR);
    EXPECT_EQ(currentState, testCurrentState);

    mockContext.ClearDirtyList();

    // set latch to NullOptional
    testCurrentState.Value().speed.ClearValue();
    EXPECT_EQ(logic->SetCurrentState(testCurrentState), CHIP_NO_ERROR);
    EXPECT_EQ(logic->GetCurrentState(currentState), CHIP_NO_ERROR);
    EXPECT_EQ(currentState, testCurrentState);
    EXPECT_TRUE(HasAttributeChanges(mockContext.GetDirtyList(), Attributes::CurrentState::Id));

    mockContext.ClearDirtyList();
}

TEST_F(TestClosureDimensionClusterLogic, TestCurrentStateQuietReportingSpeedValueChange)
{
    conformance.FeatureMap().Set(Feature::kPositioning).Set(Feature::kMotionLatching).Set(Feature::kSpeed);

    EXPECT_EQ(logic->Init(conformance, initParams), CHIP_NO_ERROR);
    mockContext.ClearDirtyList();

    GenericDimensionStateStruct testCurrentStateStruct;
    testCurrentStateStruct.position = Optional<DataModel::Nullable<chip::Percent100ths>>(1000);
    testCurrentStateStruct.latch    = Optional<DataModel::Nullable<bool>>(false);
    testCurrentStateStruct.speed    = Optional<Globals::ThreeLevelAutoEnum>(Globals::ThreeLevelAutoEnum::kLow);

    DataModel::Nullable<GenericDimensionStateStruct> testCurrentState(testCurrentStateStruct);
    DataModel::Nullable<GenericDimensionStateStruct> currentState;

    EXPECT_EQ(logic->GetCurrentState(currentState), CHIP_NO_ERROR);
    EXPECT_EQ(currentState, DataModel::NullNullable);

    mockContext.ClearDirtyList();

    // set speed as low
    EXPECT_EQ(logic->SetCurrentState(testCurrentState), CHIP_NO_ERROR);
    EXPECT_EQ(logic->GetCurrentState(currentState), CHIP_NO_ERROR);
    EXPECT_EQ(currentState, testCurrentState);

    mockContext.ClearDirtyList();

    // set speed to medium
    testCurrentState.Value().speed.SetValue(Globals::ThreeLevelAutoEnum::kMedium);
    EXPECT_EQ(logic->SetCurrentState(testCurrentState), CHIP_NO_ERROR);
    EXPECT_EQ(logic->GetCurrentState(currentState), CHIP_NO_ERROR);
    EXPECT_EQ(currentState, testCurrentState);
    EXPECT_TRUE(HasAttributeChanges(mockContext.GetDirtyList(), Attributes::CurrentState::Id));

    mockContext.ClearDirtyList();
}

} // namespace ClosureDimension
} // namespace Clusters
} // namespace app
} // namespace chip
