Skip to content

Commit 118e59e

Browse files
mirkoCrobumirkoCrobu
authored andcommitted
partial test implementation
1 parent a9fa3f7 commit 118e59e

File tree

13 files changed

+868
-4
lines changed

13 files changed

+868
-4
lines changed

internal/orchestrator/bricks/bricks.go

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -163,10 +163,6 @@ func (s *Service) BricksDetails(id string, idProvider *app.IDProvider,
163163
}
164164
})
165165

166-
/*qui mi serve una funzione per calcolare questo. devo iterare su ogni app, di esempio o no.
167-
ho già la funzione appList che mi può aiutare.
168-
e per ogni elemento se ho il bircikc id corrente
169-
mi creo un AppReference*/
170166
appList, err := getAppList(cfg)
171167
if err != nil {
172168
slog.Error("unable to get app list", slog.String("error", err.Error()))
Lines changed: 230 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,230 @@
1+
package bricks
2+
3+
import (
4+
"os"
5+
"testing"
6+
7+
"github.com/arduino/go-paths-helper"
8+
"github.com/stretchr/testify/assert"
9+
"github.com/stretchr/testify/require"
10+
11+
"github.com/arduino/arduino-app-cli/internal/orchestrator/app"
12+
"github.com/arduino/arduino-app-cli/internal/orchestrator/bricksindex"
13+
"github.com/arduino/arduino-app-cli/internal/orchestrator/config"
14+
"github.com/arduino/arduino-app-cli/internal/store"
15+
)
16+
17+
func TestBricksDetails________todo___________(t *testing.T) {
18+
basedir := paths.New("testdata", "assets", "0.4.8").String()
19+
service := setupTestService(t, basedir)
20+
testDataAssetsPath := paths.New(basedir)
21+
22+
testDir := paths.New("testdata")
23+
t.Setenv("ARDUINO_APP_CLI__APPS_DIR", testDir.Join("apps").String())
24+
t.Setenv("ARDUINO_APP_CLI__CONFIG_DIR", testDir.Join("config").String())
25+
t.Setenv("ARDUINO_APP_CLI__DATA_DIR", testDir.String())
26+
27+
cfg, err := config.NewFromEnv()
28+
require.NoError(t, err)
29+
idProvider := app.NewAppIDProvider(cfg)
30+
31+
expectedVars := map[string]BrickVariable{
32+
"ARDUINO_DEVICE_ID": {
33+
DefaultValue: "",
34+
Description: "Arduino Cloud Device ID",
35+
Required: true,
36+
},
37+
"ARDUINO_SECRET": {
38+
DefaultValue: "",
39+
Description: "Arduino Cloud Secret",
40+
Required: true,
41+
},
42+
}
43+
44+
readmePath := testDataAssetsPath.Join("docs", "arduino", "arduino_cloud", "README.md")
45+
expectedReadmeBytes, err := os.ReadFile(readmePath.String())
46+
require.NoError(t, err, "Failed to read test readme file")
47+
expectedReadme := string(expectedReadmeBytes)
48+
expectedAPIPath := testDataAssetsPath.Join("api-docs", "arduino", "app_bricks", "arduino_cloud", "API.md").String()
49+
examplesBasePath := testDataAssetsPath.Join("examples", "arduino", "arduino_cloud")
50+
expectedExamples := []CodeExample{
51+
{Path: examplesBasePath.Join("1_led_blink.py").String()},
52+
{Path: examplesBasePath.Join("2_light_with_colors_monitor.py").String()},
53+
{Path: examplesBasePath.Join("3_light_with_colors_command.py").String()},
54+
}
55+
expectedUsedByApps := []AppReference{
56+
{ID: "L2hvbWUvbWlya29jcm9idS9hcmR1aW5vX3Byb2plY3RzL2FyZHVpbm8tYXBwLWNsaS9pbnRlcm5hbC9vcmNoZXN0cmF0b3IvYnJpY2tzL3Rlc3RkYXRhL2V4YW1wbGVzL2Nsb3VkLWJsaW5r",
57+
Name: "Blinking LED from Arduino Cloud",
58+
Icon: "☁️",
59+
},
60+
}
61+
62+
testCases := []struct {
63+
name string
64+
brickID string
65+
wantErr bool
66+
wantErrMsg string
67+
expectedResult BrickDetailsResult
68+
}{
69+
{
70+
name: "Success - brick found",
71+
brickID: "arduino:arduino_cloud",
72+
wantErr: false,
73+
expectedResult: BrickDetailsResult{
74+
ID: "arduino:arduino_cloud",
75+
Name: "Arduino Cloud",
76+
Author: "Arduino",
77+
Description: "Connects to Arduino Cloud",
78+
Category: "",
79+
Status: "installed",
80+
Variables: expectedVars,
81+
Readme: expectedReadme,
82+
ApiDocsPath: expectedAPIPath,
83+
CodeExamples: expectedExamples,
84+
UsedByApps: expectedUsedByApps,
85+
},
86+
},
87+
{
88+
name: "Error - brick not found",
89+
brickID: "arduino:non_existing_brick",
90+
wantErr: true,
91+
wantErrMsg: "brick not found",
92+
},
93+
}
94+
95+
for _, tc := range testCases {
96+
t.Run(tc.name, func(t *testing.T) {
97+
result, err := service.BricksDetails(tc.brickID, idProvider, cfg)
98+
99+
if tc.wantErr {
100+
require.Error(t, err)
101+
if tc.wantErrMsg != "" {
102+
require.Contains(t, err.Error(), tc.wantErrMsg)
103+
}
104+
assert.Equal(t, BrickDetailsResult{}, result)
105+
return
106+
}
107+
require.NoError(t, err)
108+
assert.Equal(t, tc.expectedResult, result)
109+
})
110+
}
111+
}
112+
113+
func TestBricksDetails(t *testing.T) {
114+
115+
baseDir := paths.New("testdata", "assets", "0.4.8").String()
116+
service := setupTestService(t, baseDir)
117+
testDataAssetsPath := paths.New(baseDir)
118+
119+
cfg, err := config.NewFromEnv()
120+
require.NoError(t, err)
121+
idProvider := app.NewAppIDProvider(cfg)
122+
123+
testCases := []struct {
124+
name string
125+
brickID string
126+
wantErr bool
127+
wantErrMsg string
128+
expectedResult BrickDetailsResult
129+
}{
130+
{
131+
name: "Success - brick found",
132+
brickID: "arduino:arduino_cloud",
133+
wantErr: false,
134+
expectedResult: BrickDetailsResult{
135+
ID: "arduino:arduino_cloud",
136+
Name: "Arduino Cloud",
137+
Author: "Arduino",
138+
Description: "Connects to Arduino Cloud",
139+
Category: "",
140+
Status: "installed",
141+
Variables: map[string]BrickVariable{
142+
"ARDUINO_DEVICE_ID": {
143+
DefaultValue: "<YOUR_DEVICE_ID>",
144+
Description: "Arduino Cloud Device ID",
145+
Required: false,
146+
},
147+
"ARDUINO_SECRET": {
148+
DefaultValue: "<YOUR_SECRET>",
149+
Description: "Arduino Cloud Secret",
150+
Required: false,
151+
},
152+
},
153+
Readme: string(mustReadFile(t, testDataAssetsPath.Join(
154+
"docs", "arduino", "arduino_cloud", "README.md",
155+
).String())),
156+
ApiDocsPath: testDataAssetsPath.Join(
157+
"api-docs", "arduino", "app_bricks", "arduino_cloud", "API.md",
158+
).String(),
159+
CodeExamples: []CodeExample{
160+
{Path: testDataAssetsPath.Join("examples", "arduino", "arduino_cloud", "1_led_blink.py").String()},
161+
{Path: testDataAssetsPath.Join("examples", "arduino", "arduino_cloud", "2_light_with_colors_monitor.py").String()},
162+
{Path: testDataAssetsPath.Join("examples", "arduino", "arduino_cloud", "3_light_with_colors_command.py").String()},
163+
},
164+
},
165+
},
166+
{
167+
name: "Error - brick not found",
168+
brickID: "arduino:non_existing_brick",
169+
wantErr: true,
170+
wantErrMsg: "brick not found",
171+
},
172+
{
173+
name: "Success - brick with nil examples",
174+
brickID: "arduino:streamlit_ui",
175+
wantErr: false,
176+
expectedResult: BrickDetailsResult{
177+
ID: "arduino:streamlit_ui",
178+
Name: "WebUI - Streamlit",
179+
Author: "Arduino",
180+
Description: "A simplified user interface based on Streamlit and Python.",
181+
Category: "ui",
182+
Status: "installed",
183+
Variables: map[string]BrickVariable{},
184+
Readme: string(mustReadFile(t, testDataAssetsPath.Join(
185+
"docs", "arduino", "streamlit_ui", "README.md",
186+
).String())),
187+
ApiDocsPath: testDataAssetsPath.Join(
188+
"api-docs", "arduino", "app_bricks", "streamlit_ui", "API.md",
189+
).String(),
190+
CodeExamples: []CodeExample{},
191+
},
192+
},
193+
}
194+
for _, tc := range testCases {
195+
t.Run(tc.name, func(t *testing.T) {
196+
result, err := service.BricksDetails(tc.brickID, idProvider, cfg)
197+
198+
if tc.wantErr {
199+
// --- Error Case ---
200+
require.Error(t, err)
201+
if tc.wantErrMsg != "" {
202+
require.Contains(t, err.Error(), tc.wantErrMsg)
203+
}
204+
assert.Equal(t, BrickDetailsResult{}, result)
205+
return
206+
}
207+
208+
// --- Success Case ---
209+
require.NoError(t, err)
210+
assert.Equal(t, tc.expectedResult, result)
211+
})
212+
}
213+
}
214+
215+
func setupTestService(t *testing.T, baseDir string) *Service {
216+
store := store.NewStaticStore(baseDir)
217+
218+
bricksIndex, err := bricksindex.GenerateBricksIndexFromFile(paths.New(baseDir))
219+
require.NoError(t, err)
220+
221+
service := NewService(nil, bricksIndex, store)
222+
return service
223+
}
224+
225+
func mustReadFile(t *testing.T, path string) []byte {
226+
t.Helper()
227+
bytes, err := os.ReadFile(path)
228+
require.NoError(t, err, "failed to read test file: %s", path)
229+
return bytes
230+
}
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
# arduino_cloud API Reference
2+
3+
## Index
4+
5+
- Class `ArduinoCloud`
6+
7+
---
8+
9+
## `ArduinoCloud` class
10+
11+
```python
12+
class ArduinoCloud(device_id: str, secret: str, server: str, port: int)
13+
```
14+
15+
Arduino Cloud client for managing devices and data.
16+
17+
### Parameters
18+
19+
- **device_id** (*str*): The unique identifier for the device.
20+
If omitted, uses ARDUINO_DEVICE_ID environment variable.
21+
- **secret** (*str*): The password for Arduino Cloud authentication.
22+
If omitted, uses ARDUINO_SECRET environment variable.
23+
- **server** (*str*) (optional): The server address for Arduino Cloud (default: "iot.arduino.cc").
24+
- **port** (*int*) (optional): The port to connect to the Arduino Cloud server (default: 8884).
25+
26+
### Raises
27+
28+
- **ValueError**: If either device_id or secret is not provided explicitly or via environment variable.
29+
30+
### Methods
31+
32+
#### `start()`
33+
34+
Start the Arduino IoT Cloud client.
35+
36+
#### `loop()`
37+
38+
Run a single iteration of the Arduino IoT Cloud client loop, processing commands and updating state.
39+
40+
#### `register(aiotobj: str | Any)`
41+
42+
Register a variable or object with the Arduino Cloud client.
43+
44+
##### Parameters
45+
46+
- **aiotobj** (*str | Any*): The variable name or object from which to derive the variable name to register.
47+
- ****kwargs** (*Any*): Additional keyword arguments for registration.
48+

0 commit comments

Comments
 (0)