@@ -61,3 +61,109 @@ test(
6161 } ,
6262 timeout . short ( )
6363)
64+
65+ // extractUcClusterCode and getClusterIdsByUcComponents together back the
66+ // "Required SLC Component not installed" warning. They reduce UC component
67+ // ids to a canonical short cluster code so selected ids (from Studio's tree)
68+ // and required ids (from the ZCL extension's component map) can be compared
69+ // regardless of which prefix format the source happens to use.
70+ test (
71+ 'extractUcClusterCode: collapses all known id formats to the short code' ,
72+ ( ) => {
73+ // Studio tree leaf, zigbee
74+ expect (
75+ util . extractUcClusterCode (
76+ 'studiocomproot-Zigbee-Cluster_Library-Common-zigbee_basic'
77+ )
78+ ) . toEqual ( 'zigbee_basic' )
79+
80+ // Studio tree leaf, matter
81+ expect (
82+ util . extractUcClusterCode (
83+ 'studiocomproot-Matter-Clusters-Common-matter_basic'
84+ )
85+ ) . toEqual ( 'matter_basic' )
86+
87+ // %extension form used by the ZCL extension required-component map
88+ expect ( util . extractUcClusterCode ( '%extension-zigbee%zigbee_basic' ) ) . toEqual (
89+ 'zigbee_basic'
90+ )
91+ expect (
92+ util . extractUcClusterCode ( '%extension-matter%matter_level_control' )
93+ ) . toEqual ( 'matter_level_control' )
94+
95+ // Composite path with %extension inside (what Studio sends for matter)
96+ expect (
97+ util . extractUcClusterCode (
98+ 'matter:1.0.0-Matter-Clusters-%extension-matter%matter_level_control'
99+ )
100+ ) . toEqual ( 'matter_level_control' )
101+
102+ // Bare short code passes through
103+ expect ( util . extractUcClusterCode ( 'zigbee_basic' ) ) . toEqual ( 'zigbee_basic' )
104+
105+ // Defensive cases
106+ expect ( util . extractUcClusterCode ( null ) ) . toEqual ( '' )
107+ expect ( util . extractUcClusterCode ( undefined ) ) . toEqual ( '' )
108+ expect ( util . extractUcClusterCode ( '' ) ) . toEqual ( '' )
109+ } ,
110+ timeout . short ( )
111+ )
112+
113+ test (
114+ 'getClusterIdsByUcComponents: maps mixed zigbee+matter components to short codes' ,
115+ ( ) => {
116+ const components = [
117+ { id : 'studiocomproot-Zigbee-Cluster_Library-Common-zigbee_basic' } ,
118+ { id : 'studiocomproot-Zigbee-Cluster_Library-HA-zigbee_on_off' } ,
119+ {
120+ id : 'matter:1.0.0-Matter-Clusters-%extension-matter%matter_level_control'
121+ } ,
122+ { id : '%extension-matter%matter_basic' }
123+ ]
124+ expect ( util . getClusterIdsByUcComponents ( components ) ) . toEqual ( [
125+ 'zigbee_basic' ,
126+ 'zigbee_on_off' ,
127+ 'matter_level_control' ,
128+ 'matter_basic'
129+ ] )
130+ } ,
131+ timeout . short ( )
132+ )
133+
134+ test (
135+ 'getClusterIdsByUcComponents + extractUcClusterCode: matter and zigbee required ids both match' ,
136+ ( ) => {
137+ // Mirrors the comparison in common-mixin's missingUcComponentDependencies:
138+ // selectedIds = getClusterIdsByUcComponents(selected)
139+ // missing = required.filter(r => !selectedIds.includes(extractUcClusterCode(r)))
140+ const selected = [
141+ { id : 'studiocomproot-Zigbee-Cluster_Library-Common-zigbee_basic' } ,
142+ {
143+ id : 'matter:1.0.0-Matter-Clusters-%extension-matter%matter_level_control'
144+ }
145+ ]
146+ const selectedIds = util . getClusterIdsByUcComponents ( selected )
147+
148+ // Required ids come from the ZCL extension in %extension-...%name form.
149+ const required = [
150+ '%extension-zigbee%zigbee_basic' ,
151+ '%extension-matter%matter_level_control'
152+ ]
153+ const missing = required . filter (
154+ ( id ) => ! selectedIds . includes ( util . extractUcClusterCode ( id ) )
155+ )
156+ expect ( missing ) . toEqual ( [ ] )
157+
158+ // Anything genuinely not in selected stays in the missing list.
159+ const requiredWithGap = [
160+ '%extension-zigbee%zigbee_basic' ,
161+ '%extension-zigbee%zigbee_on_off' // not selected
162+ ]
163+ const missingWithGap = requiredWithGap . filter (
164+ ( id ) => ! selectedIds . includes ( util . extractUcClusterCode ( id ) )
165+ )
166+ expect ( missingWithGap ) . toEqual ( [ '%extension-zigbee%zigbee_on_off' ] )
167+ } ,
168+ timeout . short ( )
169+ )
0 commit comments