1+ #include < lib/core/StringBuilderAdapters.h>
2+ #include < pw_unit_test/framework.h>
3+ #include < app/data-model/Nullable.h>
4+
5+ #include " ClosureManager.h"
6+ #include " ClosureControlEndpoint.h"
7+ #include " ClosureDimensionEndpoint.h"
8+
9+ using namespace chip ;
10+ using namespace chip ::app;
11+ using namespace chip ::app::DataModel;
12+ using namespace chip ::app::Clusters;
13+ using namespace chip ::app::Clusters::ClosureControl;
14+ using namespace chip ::app::Clusters::ClosureDimension;
15+
16+ // Stub/mock classes for dependencies
17+ class MockClosureControlEndpoint : public ClosureControlEndpoint
18+ {
19+ public:
20+ CHIP_ERROR InitCalled = CHIP_ERROR_INTERNAL;
21+ CHIP_ERROR Init () override
22+ {
23+ InitCalled = CHIP_NO_ERROR;
24+ return CHIP_NO_ERROR;
25+ }
26+ ClosureControl::ClusterConformance GetConformance () override
27+ {
28+ return ClosureControl::ClusterConformance ().Set (ClosureControl::Feature::kPositioning );
29+ }
30+ };
31+
32+ class MockClosureDimensionEndpoint : public ClosureDimensionEndpoint
33+ {
34+ public:
35+ CHIP_ERROR InitCalled = CHIP_ERROR_INTERNAL;
36+ CHIP_ERROR Init () override
37+ {
38+ InitCalled = CHIP_NO_ERROR;
39+ return CHIP_NO_ERROR;
40+ }
41+ ClosureDimension::ClusterConformance GetConformance () override
42+ {
43+ return ClosureDimension::ClusterConformance ().Set (ClosureDimension::Feature::kPositioning );
44+ }
45+ };
46+
47+ namespace {
48+
49+ TEST (ClosureManagerValidation, InitialStateIsCorrect)
50+ {
51+ ClosureManager & mgr = ClosureManager::GetInstance ();
52+ // After construction, default action should be INVALID_ACTION and endpoint id invalid
53+ EXPECT_EQ (mgr.GetCurrentAction (), ClosureManager::Action_t::INVALID_ACTION);
54+ EXPECT_EQ (mgr.mCurrentActionEndpointId , chip::kInvalidEndpointId );
55+ }
56+
57+ TEST (ClosureManagerValidation, InitSetsUpEndpointsAndTags)
58+ {
59+ ClosureManager & mgr = ClosureManager::GetInstance ();
60+ // Call Init and expect no crash (side effects are hard to check, but timer creation and endpoint init are called)
61+ mgr.Init ();
62+ // After Init, endpoints should be initialized (no direct way to check, but no error thrown)
63+ EXPECT_TRUE (true );
64+ }
65+
66+ TEST (ClosureManagerValidation, SetClosureControlInitialStateAcceptsValidEndpoint)
67+ {
68+ ClosureManager & mgr = ClosureManager::GetInstance ();
69+ MockClosureControlEndpoint mockEndpoint;
70+ CHIP_ERROR err = mgr.SetClosureControlInitialState (mockEndpoint);
71+ EXPECT_EQ (err, CHIP_NO_ERROR);
72+ }
73+
74+ TEST (ClosureManagerValidation, SetClosurePanelInitialStateAcceptsValidEndpoint)
75+ {
76+ ClosureManager & mgr = ClosureManager::GetInstance ();
77+ MockClosureDimensionEndpoint mockEndpoint;
78+ CHIP_ERROR err = mgr.SetClosurePanelInitialState (mockEndpoint);
79+ EXPECT_EQ (err, CHIP_NO_ERROR);
80+ }
81+
82+ TEST (ClosureManagerValidation, GetPanelNextPositionIncreasesPosition)
83+ {
84+ ClosureManager & mgr = ClosureManager::GetInstance ();
85+ GenericDimensionStateStruct current, target;
86+ current.position .SetValue (DataModel::MakeNullable<Percent100ths>(1000 ));
87+ target.position .SetValue (DataModel::MakeNullable<Percent100ths>(5000 ));
88+ DataModel::Nullable<Percent100ths> next;
89+ bool result = mgr.GetPanelNextPosition (current, target, next);
90+ EXPECT_TRUE (result);
91+ EXPECT_EQ (next.Value (), 3000 ); // 1000 + 2000 step
92+ }
93+
94+ TEST (ClosureManagerValidation, GetPanelNextPositionDecreasesPosition)
95+ {
96+ ClosureManager & mgr = ClosureManager::GetInstance ();
97+ GenericDimensionStateStruct current, target;
98+ current.position .SetValue (DataModel::MakeNullable<Percent100ths>(8000 ));
99+ target.position .SetValue (DataModel::MakeNullable<Percent100ths>(2000 ));
100+ DataModel::Nullable<Percent100ths> next;
101+ bool result = mgr.GetPanelNextPosition (current, target, next);
102+ EXPECT_TRUE (result);
103+ EXPECT_EQ (next.Value (), 6000 ); // 8000 - 2000 step
104+ }
105+
106+ TEST (ClosureManagerValidation, GetPanelNextPositionAtTargetReturnsFalse)
107+ {
108+ ClosureManager & mgr = ClosureManager::GetInstance ();
109+ GenericDimensionStateStruct current, target;
110+ current.position .SetValue (DataModel::MakeNullable<Percent100ths>(4000 ));
111+ target.position .SetValue (DataModel::MakeNullable<Percent100ths>(4000 ));
112+ DataModel::Nullable<Percent100ths> next;
113+ bool result = mgr.GetPanelNextPosition (current, target, next);
114+ EXPECT_FALSE (result);
115+ EXPECT_EQ (next.Value (), 4000 );
116+ }
117+
118+ TEST (ClosureManagerValidation, GetPanelNextPositionFailsWithNullTarget)
119+ {
120+ ClosureManager & mgr = ClosureManager::GetInstance ();
121+ GenericDimensionStateStruct current, target;
122+ current.position .SetValue (DataModel::MakeNullable<Percent100ths>(1000 ));
123+ // target.position left unset (null)
124+ DataModel::Nullable<Percent100ths> next;
125+ bool result = mgr.GetPanelNextPosition (current, target, next);
126+ EXPECT_FALSE (result);
127+ }
128+
129+ TEST (ClosureManagerValidation, GetPanelNextPositionFailsWithNullCurrent)
130+ {
131+ ClosureManager & mgr = ClosureManager::GetInstance ();
132+ GenericDimensionStateStruct current, target;
133+ // current.position left unset (null)
134+ target.position .SetValue (DataModel::MakeNullable<Percent100ths>(5000 ));
135+ DataModel::Nullable<Percent100ths> next;
136+ bool result = mgr.GetPanelNextPosition (current, target, next);
137+ EXPECT_FALSE (result);
138+ }
139+
140+ TEST (ClosureManagerValidation, GetPanelEndpointByIdReturnsCorrectPointer)
141+ {
142+ ClosureManager & mgr = ClosureManager::GetInstance ();
143+ mgr.Init ();
144+ ClosureDimensionEndpoint * ep2 = mgr.GetPanelEndpointById (mgr.mClosurePanelEndpoint2 .GetEndpointId ());
145+ ClosureDimensionEndpoint * ep3 = mgr.GetPanelEndpointById (mgr.mClosurePanelEndpoint3 .GetEndpointId ());
146+ EXPECT_EQ (ep2, &mgr.mClosurePanelEndpoint2 );
147+ EXPECT_EQ (ep3, &mgr.mClosurePanelEndpoint3 );
148+ }
149+
150+ TEST (ClosureManagerValidation, GetPanelEndpointByIdReturnsNullForInvalidId)
151+ {
152+ ClosureManager & mgr = ClosureManager::GetInstance ();
153+ mgr.Init ();
154+ ClosureDimensionEndpoint * ep = mgr.GetPanelEndpointById (0xFF ); // Invalid endpoint id
155+ EXPECT_EQ (ep, nullptr );
156+ }
157+
158+ } // namespace
0 commit comments