@@ -24,6 +24,7 @@ import (
2424
2525 "github.com/arduino/arduino-app-cli/internal/orchestrator/app"
2626 "github.com/arduino/arduino-app-cli/internal/orchestrator/bricksindex"
27+ "github.com/arduino/arduino-app-cli/internal/orchestrator/modelsindex"
2728)
2829
2930func TestBrickCreate (t * testing.T ) {
@@ -190,3 +191,155 @@ func TestGetBrickInstanceVariableDetails(t *testing.T) {
190191 })
191192 }
192193}
194+
195+ func TestAppBrickInstanceModelsDetails (t * testing.T ) {
196+
197+ bIndex := & bricksindex.BricksIndex {
198+ Bricks : []bricksindex.Brick {
199+ {
200+ ID : "arduino:object_detection" ,
201+ Name : "Object Detection" ,
202+ Category : "video" ,
203+ ModelName : "yolox-object-detection" , // Default model
204+ Variables : []bricksindex.BrickVariable {
205+ {Name : "EI_OBJ_DETECTION_MODEL" , DefaultValue : "default_path" , Description : "path to the model file" },
206+ {Name : "CUSTOM_MODEL_PATH" , DefaultValue : "/home/arduino/.arduino-bricks/ei-models" , Description : "path to the custom model directory" },
207+ },
208+ },
209+ {
210+ ID : "arduino:weather_forecast" ,
211+ Name : "Weather Forecast" ,
212+ Category : "miscellaneous" ,
213+ ModelName : "" ,
214+ },
215+ },
216+ }
217+
218+ mIndex := & modelsindex.ModelsIndex {
219+ Models : []modelsindex.AIModel {
220+
221+ {
222+ ID : "yolox-object-detection" ,
223+ Name : "General purpose object detection - YoloX" ,
224+ ModuleDescription : "General purpose object detection..." ,
225+ Bricks : []string {"arduino:object_detection" , "arduino:video_object_detection" },
226+ },
227+ {
228+ ID : "face-detection" ,
229+ Name : "Lightweight-Face-Detection" ,
230+ Bricks : []string {"arduino:object_detection" , "arduino:video_object_detection" },
231+ },
232+ }}
233+
234+ svc := & Service {
235+ bricksIndex : bIndex ,
236+ modelsIndex : mIndex ,
237+ }
238+
239+ tests := []struct {
240+ name string
241+ app * app.ArduinoApp
242+ brickID string
243+ expectedError string
244+ validate func (* testing.T , BrickInstance )
245+ }{
246+ {
247+ name : "Brick not found in global Index" ,
248+ brickID : "arduino:non_existent_brick" ,
249+ app : & app.ArduinoApp {
250+ Descriptor : app.AppDescriptor {Bricks : []app.Brick {}},
251+ },
252+ expectedError : "brick not found" ,
253+ },
254+ {
255+ name : "Brick found in Index but not added to App" ,
256+ brickID : "arduino:object_detection" ,
257+ app : & app.ArduinoApp {
258+ Descriptor : app.AppDescriptor {
259+ Bricks : []app.Brick {
260+ {ID : "arduino:weather_forecast" },
261+ },
262+ },
263+ },
264+ expectedError : "brick arduino:object_detection not added in the app" ,
265+ },
266+ {
267+ name : "Success - Standard Brick without Model" ,
268+ brickID : "arduino:weather_forecast" ,
269+ app : & app.ArduinoApp {
270+ Descriptor : app.AppDescriptor {
271+ Bricks : []app.Brick {
272+ {ID : "arduino:weather_forecast" },
273+ },
274+ },
275+ },
276+ validate : func (t * testing.T , res BrickInstance ) {
277+ require .Equal (t , "arduino:weather_forecast" , res .ID )
278+ require .Equal (t , "Weather Forecast" , res .Name )
279+ require .Equal (t , "installed" , res .Status )
280+ require .Empty (t , res .ModelID )
281+ require .Empty (t , res .CompatibleModels )
282+ },
283+ },
284+ {
285+ name : "Success - Brick with Default Model" ,
286+ brickID : "arduino:object_detection" ,
287+ app : & app.ArduinoApp {
288+ Descriptor : app.AppDescriptor {
289+ Bricks : []app.Brick {
290+ {
291+ ID : "arduino:object_detection" ,
292+ },
293+ },
294+ },
295+ },
296+ validate : func (t * testing.T , res BrickInstance ) {
297+ require .Equal (t , "arduino:object_detection" , res .ID )
298+ require .Equal (t , "yolox-object-detection" , res .ModelID )
299+ require .Len (t , res .CompatibleModels , 2 )
300+ require .Equal (t , "yolox-object-detection" , res .CompatibleModels [0 ].ID )
301+ require .Equal (t , "face-detection" , res .CompatibleModels [1 ].ID )
302+ },
303+ },
304+ {
305+ name : "Success - Brick with Overridden Model in App" ,
306+ brickID : "arduino:object_detection" ,
307+ app : & app.ArduinoApp {
308+ Descriptor : app.AppDescriptor {
309+ Bricks : []app.Brick {
310+ {
311+ ID : "arduino:object_detection" ,
312+ Model : "face-detection" ,
313+ },
314+ },
315+ },
316+ },
317+ validate : func (t * testing.T , res BrickInstance ) {
318+ require .Equal (t , "arduino:object_detection" , res .ID )
319+ require .Equal (t , "face-detection" , res .ModelID )
320+ require .Len (t , res .CompatibleModels , 2 )
321+ require .Equal (t , "yolox-object-detection" , res .CompatibleModels [0 ].ID )
322+ require .Equal (t , "face-detection" , res .CompatibleModels [1 ].ID )
323+ },
324+ },
325+ }
326+
327+ for _ , tt := range tests {
328+ t .Run (tt .name , func (t * testing.T ) {
329+ result , err := svc .AppBrickInstanceDetails (tt .app , tt .brickID )
330+
331+ if tt .expectedError != "" {
332+ require .Error (t , err )
333+ if err != nil {
334+ require .Contains (t , err .Error (), tt .expectedError )
335+ }
336+ return
337+ }
338+
339+ require .NoError (t , err )
340+ if tt .validate != nil {
341+ tt .validate (t , result )
342+ }
343+ })
344+ }
345+ }
0 commit comments