1 /* test_vcp.c - unit test for volume settings */
2 
3 /*
4  * Copyright (c) 2024 Nordic Semiconductor ASA
5  *
6  * SPDX-License-Identifier: Apache-2.0
7  */
8 
9 #include <stdlib.h>
10 
11 #include <zephyr/bluetooth/audio/cap.h>
12 #include <zephyr/bluetooth/audio/vcp.h>
13 #include <zephyr/fff.h>
14 
15 #include "bluetooth.h"
16 #include "cap_commander.h"
17 #include "conn.h"
18 #include "expects_util.h"
19 #include "cap_mocks.h"
20 #include "test_common.h"
21 
22 #define FFF_GLOBALS
23 
24 struct cap_commander_test_vcp_fixture {
25 	struct bt_conn conns[CONFIG_BT_MAX_CONN];
26 };
27 
cap_commander_test_vcp_fixture_init(struct cap_commander_test_vcp_fixture * fixture)28 static void cap_commander_test_vcp_fixture_init(struct cap_commander_test_vcp_fixture *fixture)
29 {
30 	for (size_t i = 0; i < ARRAY_SIZE(fixture->conns); i++) {
31 		test_conn_init(&fixture->conns[i]);
32 	}
33 }
34 
cap_commander_test_vcp_setup(void)35 static void *cap_commander_test_vcp_setup(void)
36 {
37 	struct cap_commander_test_vcp_fixture *fixture;
38 
39 	fixture = malloc(sizeof(*fixture));
40 	zassert_not_null(fixture);
41 
42 	return fixture;
43 }
44 
cap_commander_test_vcp_before(void * f)45 static void cap_commander_test_vcp_before(void *f)
46 {
47 	memset(f, 0, sizeof(struct cap_commander_test_vcp_fixture));
48 	cap_commander_test_vcp_fixture_init(f);
49 }
50 
cap_commander_test_vcp_after(void * f)51 static void cap_commander_test_vcp_after(void *f)
52 {
53 	struct cap_commander_test_vcp_fixture *fixture = f;
54 
55 	bt_cap_commander_unregister_cb(&mock_cap_commander_cb);
56 
57 	for (size_t i = 0; i < ARRAY_SIZE(fixture->conns); i++) {
58 		mock_bt_conn_disconnected(&fixture->conns[i], BT_HCI_ERR_REMOTE_USER_TERM_CONN);
59 	}
60 }
61 
cap_commander_test_vcp_teardown(void * f)62 static void cap_commander_test_vcp_teardown(void *f)
63 {
64 	free(f);
65 }
66 
67 ZTEST_SUITE(cap_commander_test_vcp, NULL, cap_commander_test_vcp_setup,
68 	    cap_commander_test_vcp_before, cap_commander_test_vcp_after,
69 	    cap_commander_test_vcp_teardown);
70 
ZTEST_F(cap_commander_test_vcp,test_commander_change_volume)71 ZTEST_F(cap_commander_test_vcp, test_commander_change_volume)
72 {
73 	union bt_cap_set_member members[ARRAY_SIZE(fixture->conns)];
74 	const struct bt_cap_commander_change_volume_param param = {
75 		.type = BT_CAP_SET_TYPE_AD_HOC,
76 		.members = members,
77 		.count = ARRAY_SIZE(fixture->conns),
78 		.volume = 177,
79 	};
80 	int err;
81 
82 	for (size_t i = 0U; i < ARRAY_SIZE(members); i++) {
83 		members[i].member = &fixture->conns[i];
84 	}
85 
86 	err = bt_cap_commander_register_cb(&mock_cap_commander_cb);
87 	zassert_equal(0, err, "Unexpected return value %d", err);
88 
89 	for (size_t i = 0; i < ARRAY_SIZE(fixture->conns); i++) {
90 		struct bt_vcp_vol_ctlr *vol_ctlr; /* We don't care about this */
91 
92 		err = bt_vcp_vol_ctlr_discover(&fixture->conns[i], &vol_ctlr);
93 		zassert_equal(0, err, "Unexpected return value %d", err);
94 	}
95 
96 	err = bt_cap_commander_change_volume(&param);
97 	zassert_equal(0, err, "Unexpected return value %d", err);
98 
99 	zexpect_call_count("bt_cap_commander_cb.volume_changed", 1,
100 			   mock_cap_commander_volume_changed_cb_fake.call_count);
101 }
102 
ZTEST_F(cap_commander_test_vcp,test_commander_change_volume_double)103 ZTEST_F(cap_commander_test_vcp, test_commander_change_volume_double)
104 {
105 	union bt_cap_set_member members[ARRAY_SIZE(fixture->conns)];
106 	const struct bt_cap_commander_change_volume_param param = {
107 		.type = BT_CAP_SET_TYPE_AD_HOC,
108 		.members = members,
109 		.count = ARRAY_SIZE(fixture->conns),
110 		.volume = 177,
111 	};
112 	int err;
113 
114 	for (size_t i = 0U; i < ARRAY_SIZE(members); i++) {
115 		members[i].member = &fixture->conns[i];
116 	}
117 
118 	err = bt_cap_commander_register_cb(&mock_cap_commander_cb);
119 	zassert_equal(0, err, "Unexpected return value %d", err);
120 
121 	for (size_t i = 0; i < ARRAY_SIZE(fixture->conns); i++) {
122 		struct bt_vcp_vol_ctlr *vol_ctlr; /* We don't care about this */
123 
124 		err = bt_vcp_vol_ctlr_discover(&fixture->conns[i], &vol_ctlr);
125 		zassert_equal(0, err, "Unexpected return value %d", err);
126 	}
127 
128 	err = bt_cap_commander_change_volume(&param);
129 	zassert_equal(0, err, "Unexpected return value %d", err);
130 
131 	zexpect_call_count("bt_cap_commander_cb.volume_changed", 1,
132 			   mock_cap_commander_volume_changed_cb_fake.call_count);
133 
134 	/* Verify that it still works as expected if we set the same value twice */
135 	err = bt_cap_commander_change_volume(&param);
136 	zassert_equal(0, err, "Unexpected return value %d", err);
137 
138 	zexpect_call_count("bt_cap_commander_cb.volume_changed", 2,
139 			   mock_cap_commander_volume_changed_cb_fake.call_count);
140 }
141 
ZTEST_F(cap_commander_test_vcp,test_commander_change_volume_inval_param_null)142 ZTEST_F(cap_commander_test_vcp, test_commander_change_volume_inval_param_null)
143 {
144 	int err;
145 
146 	err = bt_cap_commander_change_volume(NULL);
147 	zassert_equal(-EINVAL, err, "Unexpected return value %d", err);
148 }
149 
ZTEST_F(cap_commander_test_vcp,test_commander_change_volume_inval_param_null_members)150 ZTEST_F(cap_commander_test_vcp, test_commander_change_volume_inval_param_null_members)
151 {
152 	const struct bt_cap_commander_change_volume_param param = {
153 		.type = BT_CAP_SET_TYPE_AD_HOC,
154 		.members = NULL,
155 		.count = ARRAY_SIZE(fixture->conns),
156 		.volume = 177,
157 	};
158 	int err;
159 
160 	err = bt_cap_commander_change_volume(&param);
161 	zassert_equal(-EINVAL, err, "Unexpected return value %d", err);
162 }
163 
ZTEST_F(cap_commander_test_vcp,test_commander_change_volume_inval_param_null_member)164 ZTEST_F(cap_commander_test_vcp, test_commander_change_volume_inval_param_null_member)
165 {
166 	union bt_cap_set_member members[ARRAY_SIZE(fixture->conns)];
167 	const struct bt_cap_commander_change_volume_param param = {
168 		.type = BT_CAP_SET_TYPE_AD_HOC,
169 		.members = members,
170 		.count = ARRAY_SIZE(fixture->conns),
171 		.volume = 177,
172 	};
173 	int err;
174 
175 	for (size_t i = 0U; i < ARRAY_SIZE(members) - 1; i++) {
176 		members[i].member = &fixture->conns[i];
177 	}
178 	members[ARRAY_SIZE(members) - 1].member = NULL;
179 
180 	err = bt_cap_commander_change_volume(&param);
181 	zassert_equal(-EINVAL, err, "Unexpected return value %d", err);
182 }
183 
ZTEST_F(cap_commander_test_vcp,test_commander_change_volume_inval_missing_cas)184 ZTEST_F(cap_commander_test_vcp, test_commander_change_volume_inval_missing_cas)
185 {
186 	union bt_cap_set_member members[ARRAY_SIZE(fixture->conns)];
187 	const struct bt_cap_commander_change_volume_param param = {
188 		.type = BT_CAP_SET_TYPE_CSIP,
189 		.members = members,
190 		.count = ARRAY_SIZE(fixture->conns),
191 		.volume = 177,
192 	};
193 	int err;
194 
195 	for (size_t i = 0U; i < ARRAY_SIZE(members); i++) {
196 		members[i].member = &fixture->conns[i];
197 	}
198 
199 	err = bt_cap_commander_register_cb(&mock_cap_commander_cb);
200 	zassert_equal(0, err, "Unexpected return value %d", err);
201 
202 	for (size_t i = 0; i < ARRAY_SIZE(fixture->conns); i++) {
203 		struct bt_vcp_vol_ctlr *vol_ctlr; /* We don't care about this */
204 
205 		err = bt_vcp_vol_ctlr_discover(&fixture->conns[i], &vol_ctlr);
206 		zassert_equal(0, err, "Unexpected return value %d", err);
207 	}
208 
209 	err = bt_cap_commander_change_volume(&param);
210 	zassert_equal(-EINVAL, err, "Unexpected return value %d", err);
211 }
212 
ZTEST_F(cap_commander_test_vcp,test_commander_change_volume_inval_missing_vcs)213 ZTEST_F(cap_commander_test_vcp, test_commander_change_volume_inval_missing_vcs)
214 {
215 	union bt_cap_set_member members[ARRAY_SIZE(fixture->conns)];
216 	const struct bt_cap_commander_change_volume_param param = {
217 		.type = BT_CAP_SET_TYPE_AD_HOC,
218 		.members = members,
219 		.count = ARRAY_SIZE(fixture->conns),
220 		.volume = 177,
221 	};
222 	int err;
223 
224 	for (size_t i = 0U; i < ARRAY_SIZE(members); i++) {
225 		members[i].member = &fixture->conns[i];
226 	}
227 
228 	err = bt_cap_commander_register_cb(&mock_cap_commander_cb);
229 	zassert_equal(0, err, "Unexpected return value %d", err);
230 
231 	err = bt_cap_commander_change_volume(&param);
232 	zassert_equal(-EINVAL, err, "Unexpected return value %d", err);
233 }
234 
ZTEST_F(cap_commander_test_vcp,test_commander_change_volume_inval_param_zero_count)235 ZTEST_F(cap_commander_test_vcp, test_commander_change_volume_inval_param_zero_count)
236 {
237 	union bt_cap_set_member members[ARRAY_SIZE(fixture->conns)];
238 	const struct bt_cap_commander_change_volume_param param = {
239 		.type = BT_CAP_SET_TYPE_AD_HOC,
240 		.members = members,
241 		.count = 0U,
242 		.volume = 177,
243 	};
244 	int err;
245 
246 	for (size_t i = 0U; i < ARRAY_SIZE(members); i++) {
247 		members[i].member = &fixture->conns[i];
248 	}
249 
250 	err = bt_cap_commander_change_volume(&param);
251 	zassert_equal(-EINVAL, err, "Unexpected return value %d", err);
252 }
253 
ZTEST_F(cap_commander_test_vcp,test_commander_change_volume_inval_param_inval_count)254 ZTEST_F(cap_commander_test_vcp, test_commander_change_volume_inval_param_inval_count)
255 {
256 	union bt_cap_set_member members[ARRAY_SIZE(fixture->conns)];
257 	const struct bt_cap_commander_change_volume_param param = {
258 		.type = BT_CAP_SET_TYPE_AD_HOC,
259 		.members = members,
260 		.count = CONFIG_BT_MAX_CONN + 1,
261 		.volume = 177,
262 	};
263 	int err;
264 
265 	for (size_t i = 0U; i < ARRAY_SIZE(members); i++) {
266 		members[i].member = &fixture->conns[i];
267 	}
268 
269 	err = bt_cap_commander_change_volume(&param);
270 	zassert_equal(-EINVAL, err, "Unexpected return value %d", err);
271 }
272 
ZTEST_F(cap_commander_test_vcp,test_commander_change_volume_offset)273 ZTEST_F(cap_commander_test_vcp, test_commander_change_volume_offset)
274 {
275 	struct bt_cap_commander_change_volume_offset_member_param
276 		member_params[ARRAY_SIZE(fixture->conns)];
277 	const struct bt_cap_commander_change_volume_offset_param param = {
278 		.type = BT_CAP_SET_TYPE_AD_HOC,
279 		.param = member_params,
280 		.count = ARRAY_SIZE(member_params),
281 	};
282 	int err;
283 
284 	for (size_t i = 0U; i < ARRAY_SIZE(member_params); i++) {
285 		member_params[i].member.member = &fixture->conns[i];
286 		member_params[i].offset = 100 + i;
287 	}
288 
289 	err = bt_cap_commander_register_cb(&mock_cap_commander_cb);
290 	zassert_equal(0, err, "Unexpected return value %d", err);
291 
292 	for (size_t i = 0; i < ARRAY_SIZE(fixture->conns); i++) {
293 		struct bt_vcp_vol_ctlr *vol_ctlr; /* We don't care about this */
294 
295 		err = bt_vcp_vol_ctlr_discover(&fixture->conns[i], &vol_ctlr);
296 		zassert_equal(0, err, "Unexpected return value %d", err);
297 	}
298 
299 	err = bt_cap_commander_change_volume_offset(&param);
300 	zassert_equal(0, err, "Unexpected return value %d", err);
301 
302 	zexpect_call_count("bt_cap_commander_cb.volume_offset_changed", 1,
303 			   mock_cap_commander_volume_offset_changed_cb_fake.call_count);
304 }
305 
ZTEST_F(cap_commander_test_vcp,test_commander_change_volume_offset_double)306 ZTEST_F(cap_commander_test_vcp, test_commander_change_volume_offset_double)
307 {
308 	struct bt_cap_commander_change_volume_offset_member_param
309 		member_params[ARRAY_SIZE(fixture->conns)];
310 	const struct bt_cap_commander_change_volume_offset_param param = {
311 		.type = BT_CAP_SET_TYPE_AD_HOC,
312 		.param = member_params,
313 		.count = ARRAY_SIZE(member_params),
314 	};
315 	int err;
316 
317 	for (size_t i = 0U; i < ARRAY_SIZE(member_params); i++) {
318 		member_params[i].member.member = &fixture->conns[i];
319 		member_params[i].offset = 100 + i;
320 	}
321 
322 	err = bt_cap_commander_register_cb(&mock_cap_commander_cb);
323 	zassert_equal(0, err, "Unexpected return value %d", err);
324 
325 	for (size_t i = 0; i < ARRAY_SIZE(fixture->conns); i++) {
326 		struct bt_vcp_vol_ctlr *vol_ctlr; /* We don't care about this */
327 
328 		err = bt_vcp_vol_ctlr_discover(&fixture->conns[i], &vol_ctlr);
329 		zassert_equal(0, err, "Unexpected return value %d", err);
330 	}
331 
332 	err = bt_cap_commander_change_volume_offset(&param);
333 	zassert_equal(0, err, "Unexpected return value %d", err);
334 
335 	zexpect_call_count("bt_cap_commander_cb.volume_offset_changed", 1,
336 			   mock_cap_commander_volume_offset_changed_cb_fake.call_count);
337 
338 	/* Verify that it still works as expected if we set the same value twice */
339 	err = bt_cap_commander_change_volume_offset(&param);
340 	zassert_equal(0, err, "Unexpected return value %d", err);
341 
342 	zexpect_call_count("bt_cap_commander_cb.volume_offset_changed", 2,
343 			   mock_cap_commander_volume_offset_changed_cb_fake.call_count);
344 }
345 
ZTEST_F(cap_commander_test_vcp,test_commander_change_volume_offset_inval_param_null)346 ZTEST_F(cap_commander_test_vcp, test_commander_change_volume_offset_inval_param_null)
347 {
348 	int err;
349 
350 	err = bt_cap_commander_change_volume_offset(NULL);
351 	zassert_equal(-EINVAL, err, "Unexpected return value %d", err);
352 }
353 
ZTEST_F(cap_commander_test_vcp,test_commander_change_volume_offset_inval_param_null_param)354 ZTEST_F(cap_commander_test_vcp, test_commander_change_volume_offset_inval_param_null_param)
355 {
356 	const struct bt_cap_commander_change_volume_offset_param param = {
357 		.type = BT_CAP_SET_TYPE_AD_HOC,
358 		.param = NULL,
359 		.count = ARRAY_SIZE(fixture->conns),
360 	};
361 	int err;
362 
363 	err = bt_cap_commander_change_volume_offset(&param);
364 	zassert_equal(-EINVAL, err, "Unexpected return value %d", err);
365 }
366 
ZTEST_F(cap_commander_test_vcp,test_commander_change_volume_offset_inval_param_null_member)367 ZTEST_F(cap_commander_test_vcp, test_commander_change_volume_offset_inval_param_null_member)
368 {
369 	struct bt_cap_commander_change_volume_offset_member_param
370 		member_params[ARRAY_SIZE(fixture->conns)];
371 	const struct bt_cap_commander_change_volume_offset_param param = {
372 		.type = BT_CAP_SET_TYPE_AD_HOC,
373 		.param = member_params,
374 		.count = ARRAY_SIZE(member_params),
375 	};
376 	int err;
377 
378 	for (size_t i = 0U; i < ARRAY_SIZE(member_params); i++) {
379 		member_params[i].member.member = &fixture->conns[i];
380 		member_params[i].offset = 100 + i;
381 	}
382 	member_params[ARRAY_SIZE(member_params) - 1].member.member = NULL;
383 
384 	err = bt_cap_commander_change_volume_offset(&param);
385 	zassert_equal(-EINVAL, err, "Unexpected return value %d", err);
386 }
387 
ZTEST_F(cap_commander_test_vcp,test_commander_change_volume_offset_inval_missing_cas)388 ZTEST_F(cap_commander_test_vcp, test_commander_change_volume_offset_inval_missing_cas)
389 {
390 	struct bt_cap_commander_change_volume_offset_member_param
391 		member_params[ARRAY_SIZE(fixture->conns)];
392 	const struct bt_cap_commander_change_volume_offset_param param = {
393 		.type = BT_CAP_SET_TYPE_CSIP,
394 		.param = member_params,
395 		.count = ARRAY_SIZE(member_params),
396 	};
397 	int err;
398 
399 	for (size_t i = 0U; i < ARRAY_SIZE(member_params); i++) {
400 		member_params[i].member.member = &fixture->conns[i];
401 		member_params[i].offset = 100 + i;
402 	}
403 
404 	err = bt_cap_commander_register_cb(&mock_cap_commander_cb);
405 	zassert_equal(0, err, "Unexpected return value %d", err);
406 
407 	for (size_t i = 0; i < ARRAY_SIZE(fixture->conns); i++) {
408 		struct bt_vcp_vol_ctlr *vol_ctlr; /* We don't care about this */
409 
410 		err = bt_vcp_vol_ctlr_discover(&fixture->conns[i], &vol_ctlr);
411 		zassert_equal(0, err, "Unexpected return value %d", err);
412 	}
413 
414 	err = bt_cap_commander_change_volume_offset(&param);
415 	zassert_equal(-EINVAL, err, "Unexpected return value %d", err);
416 }
417 
ZTEST_F(cap_commander_test_vcp,test_commander_change_volume_offset_inval_missing_vocs)418 ZTEST_F(cap_commander_test_vcp, test_commander_change_volume_offset_inval_missing_vocs)
419 {
420 	struct bt_cap_commander_change_volume_offset_member_param
421 		member_params[ARRAY_SIZE(fixture->conns)];
422 	const struct bt_cap_commander_change_volume_offset_param param = {
423 		.type = BT_CAP_SET_TYPE_AD_HOC,
424 		.param = member_params,
425 		.count = ARRAY_SIZE(member_params),
426 	};
427 	int err;
428 
429 	for (size_t i = 0U; i < ARRAY_SIZE(member_params); i++) {
430 		member_params[i].member.member = &fixture->conns[i];
431 		member_params[i].offset = 100 + i;
432 	}
433 
434 	err = bt_cap_commander_register_cb(&mock_cap_commander_cb);
435 	zassert_equal(0, err, "Unexpected return value %d", err);
436 
437 	err = bt_cap_commander_change_volume_offset(&param);
438 	zassert_equal(-EINVAL, err, "Unexpected return value %d", err);
439 }
440 
ZTEST_F(cap_commander_test_vcp,test_commander_change_volume_offset_inval_param_zero_count)441 ZTEST_F(cap_commander_test_vcp, test_commander_change_volume_offset_inval_param_zero_count)
442 {
443 	struct bt_cap_commander_change_volume_offset_member_param
444 		member_params[ARRAY_SIZE(fixture->conns)];
445 	const struct bt_cap_commander_change_volume_offset_param param = {
446 		.type = BT_CAP_SET_TYPE_AD_HOC,
447 		.param = member_params,
448 		.count = 0U,
449 	};
450 	int err;
451 
452 	for (size_t i = 0U; i < ARRAY_SIZE(member_params); i++) {
453 		member_params[i].member.member = &fixture->conns[i];
454 		member_params[i].offset = 100 + i;
455 	}
456 
457 	err = bt_cap_commander_change_volume_offset(&param);
458 	zassert_equal(-EINVAL, err, "Unexpected return value %d", err);
459 }
460 
ZTEST_F(cap_commander_test_vcp,test_commander_change_volume_offset_inval_param_inval_count)461 ZTEST_F(cap_commander_test_vcp, test_commander_change_volume_offset_inval_param_inval_count)
462 {
463 	struct bt_cap_commander_change_volume_offset_member_param
464 		member_params[ARRAY_SIZE(fixture->conns)];
465 	const struct bt_cap_commander_change_volume_offset_param param = {
466 		.type = BT_CAP_SET_TYPE_AD_HOC,
467 		.param = member_params,
468 		.count = CONFIG_BT_MAX_CONN + 1,
469 	};
470 	int err;
471 
472 	for (size_t i = 0U; i < ARRAY_SIZE(member_params); i++) {
473 		member_params[i].member.member = &fixture->conns[i];
474 		member_params[i].offset = 100 + i;
475 	}
476 
477 	err = bt_cap_commander_change_volume_offset(&param);
478 	zassert_equal(-EINVAL, err, "Unexpected return value %d", err);
479 }
480 
ZTEST_F(cap_commander_test_vcp,test_commander_change_volume_offset_inval_param_inval_offset_max)481 ZTEST_F(cap_commander_test_vcp, test_commander_change_volume_offset_inval_param_inval_offset_max)
482 {
483 	struct bt_cap_commander_change_volume_offset_member_param
484 		member_params[ARRAY_SIZE(fixture->conns)];
485 	const struct bt_cap_commander_change_volume_offset_param param = {
486 		.type = BT_CAP_SET_TYPE_AD_HOC,
487 		.param = member_params,
488 		.count = ARRAY_SIZE(member_params),
489 	};
490 	int err;
491 
492 	for (size_t i = 0U; i < ARRAY_SIZE(member_params); i++) {
493 		member_params[i].member.member = &fixture->conns[i];
494 		member_params[i].offset = BT_VOCS_MAX_OFFSET + 1;
495 	}
496 
497 	err = bt_cap_commander_change_volume_offset(&param);
498 	zassert_equal(-EINVAL, err, "Unexpected return value %d", err);
499 }
500 
ZTEST_F(cap_commander_test_vcp,test_commander_change_volume_offset_inval_param_inval_offset_min)501 ZTEST_F(cap_commander_test_vcp, test_commander_change_volume_offset_inval_param_inval_offset_min)
502 {
503 	struct bt_cap_commander_change_volume_offset_member_param
504 		member_params[ARRAY_SIZE(fixture->conns)];
505 	const struct bt_cap_commander_change_volume_offset_param param = {
506 		.type = BT_CAP_SET_TYPE_AD_HOC,
507 		.param = member_params,
508 		.count = ARRAY_SIZE(member_params),
509 	};
510 	int err;
511 
512 	for (size_t i = 0U; i < ARRAY_SIZE(member_params); i++) {
513 		member_params[i].member.member = &fixture->conns[i];
514 		member_params[i].offset = BT_VOCS_MIN_OFFSET - 1;
515 	}
516 
517 	err = bt_cap_commander_change_volume_offset(&param);
518 	zassert_equal(-EINVAL, err, "Unexpected return value %d", err);
519 }
ZTEST_F(cap_commander_test_vcp,test_commander_change_volume_mute_state)520 ZTEST_F(cap_commander_test_vcp, test_commander_change_volume_mute_state)
521 {
522 	union bt_cap_set_member members[ARRAY_SIZE(fixture->conns)];
523 	const struct bt_cap_commander_change_volume_mute_state_param param = {
524 		.type = BT_CAP_SET_TYPE_AD_HOC,
525 		.members = members,
526 		.count = ARRAY_SIZE(fixture->conns),
527 		.mute = true,
528 	};
529 	int err;
530 
531 	for (size_t i = 0U; i < ARRAY_SIZE(members); i++) {
532 		members[i].member = &fixture->conns[i];
533 	}
534 
535 	err = bt_cap_commander_register_cb(&mock_cap_commander_cb);
536 	zassert_equal(0, err, "Unexpected return value %d", err);
537 
538 	for (size_t i = 0; i < ARRAY_SIZE(fixture->conns); i++) {
539 		struct bt_vcp_vol_ctlr *vol_ctlr; /* We don't care about this */
540 
541 		err = bt_vcp_vol_ctlr_discover(&fixture->conns[i], &vol_ctlr);
542 		zassert_equal(0, err, "Unexpected return value %d", err);
543 	}
544 
545 	err = bt_cap_commander_change_volume_mute_state(&param);
546 	zassert_equal(0, err, "Unexpected return value %d", err);
547 
548 	zexpect_call_count("bt_cap_commander_cb.volume_mute_changed", 1,
549 			   mock_cap_commander_volume_mute_changed_cb_fake.call_count);
550 }
551 
ZTEST_F(cap_commander_test_vcp,test_commander_change_volume_mute_state_double)552 ZTEST_F(cap_commander_test_vcp, test_commander_change_volume_mute_state_double)
553 {
554 	union bt_cap_set_member members[ARRAY_SIZE(fixture->conns)];
555 	const struct bt_cap_commander_change_volume_mute_state_param param = {
556 		.type = BT_CAP_SET_TYPE_AD_HOC,
557 		.members = members,
558 		.count = ARRAY_SIZE(fixture->conns),
559 		.mute = true,
560 	};
561 	int err;
562 
563 	for (size_t i = 0U; i < ARRAY_SIZE(members); i++) {
564 		members[i].member = &fixture->conns[i];
565 	}
566 
567 	err = bt_cap_commander_register_cb(&mock_cap_commander_cb);
568 	zassert_equal(0, err, "Unexpected return value %d", err);
569 
570 	for (size_t i = 0; i < ARRAY_SIZE(fixture->conns); i++) {
571 		struct bt_vcp_vol_ctlr *vol_ctlr; /* We don't care about this */
572 
573 		err = bt_vcp_vol_ctlr_discover(&fixture->conns[i], &vol_ctlr);
574 		zassert_equal(0, err, "Unexpected return value %d", err);
575 	}
576 
577 	err = bt_cap_commander_change_volume_mute_state(&param);
578 	zassert_equal(0, err, "Unexpected return value %d", err);
579 
580 	zexpect_call_count("bt_cap_commander_cb.volume_mute_changed", 1,
581 			   mock_cap_commander_volume_mute_changed_cb_fake.call_count);
582 
583 	/* Verify that it still works as expected if we set the same value twice */
584 	err = bt_cap_commander_change_volume_mute_state(&param);
585 	zassert_equal(0, err, "Unexpected return value %d", err);
586 
587 	zexpect_call_count("bt_cap_commander_cb.volume_mute_changed", 2,
588 			   mock_cap_commander_volume_mute_changed_cb_fake.call_count);
589 }
590 
ZTEST_F(cap_commander_test_vcp,test_commander_change_volume_mute_state_inval_param_null)591 ZTEST_F(cap_commander_test_vcp, test_commander_change_volume_mute_state_inval_param_null)
592 {
593 	int err;
594 
595 	err = bt_cap_commander_change_volume_mute_state(NULL);
596 	zassert_equal(-EINVAL, err, "Unexpected return value %d", err);
597 }
598 
ZTEST_F(cap_commander_test_vcp,test_commander_change_volume_mute_state_inval_param_null_members)599 ZTEST_F(cap_commander_test_vcp, test_commander_change_volume_mute_state_inval_param_null_members)
600 {
601 	const struct bt_cap_commander_change_volume_mute_state_param param = {
602 		.type = BT_CAP_SET_TYPE_AD_HOC,
603 		.members = NULL,
604 		.count = ARRAY_SIZE(fixture->conns),
605 		.mute = true,
606 	};
607 	int err;
608 
609 	err = bt_cap_commander_change_volume_mute_state(&param);
610 	zassert_equal(-EINVAL, err, "Unexpected return value %d", err);
611 }
612 
ZTEST_F(cap_commander_test_vcp,test_commander_change_volume_mute_state_inval_param_null_member)613 ZTEST_F(cap_commander_test_vcp, test_commander_change_volume_mute_state_inval_param_null_member)
614 {
615 	union bt_cap_set_member members[ARRAY_SIZE(fixture->conns)];
616 	const struct bt_cap_commander_change_volume_mute_state_param param = {
617 		.type = BT_CAP_SET_TYPE_AD_HOC,
618 		.members = members,
619 		.count = ARRAY_SIZE(fixture->conns),
620 		.mute = true,
621 	};
622 	int err;
623 
624 	for (size_t i = 0U; i < ARRAY_SIZE(members) - 1; i++) {
625 		members[i].member = &fixture->conns[i];
626 	}
627 	members[ARRAY_SIZE(members) - 1].member = NULL;
628 
629 	err = bt_cap_commander_change_volume_mute_state(&param);
630 	zassert_equal(-EINVAL, err, "Unexpected return value %d", err);
631 }
632 
ZTEST_F(cap_commander_test_vcp,test_commander_change_volume_mute_state_inval_missing_cas)633 ZTEST_F(cap_commander_test_vcp, test_commander_change_volume_mute_state_inval_missing_cas)
634 {
635 	union bt_cap_set_member members[ARRAY_SIZE(fixture->conns)];
636 	const struct bt_cap_commander_change_volume_mute_state_param param = {
637 		.type = BT_CAP_SET_TYPE_CSIP,
638 		.members = members,
639 		.count = ARRAY_SIZE(fixture->conns),
640 		.mute = true,
641 	};
642 	int err;
643 
644 	for (size_t i = 0U; i < ARRAY_SIZE(members); i++) {
645 		members[i].member = &fixture->conns[i];
646 	}
647 
648 	err = bt_cap_commander_register_cb(&mock_cap_commander_cb);
649 	zassert_equal(0, err, "Unexpected return value %d", err);
650 
651 	for (size_t i = 0; i < ARRAY_SIZE(fixture->conns); i++) {
652 		struct bt_vcp_vol_ctlr *vol_ctlr; /* We don't care about this */
653 
654 		err = bt_vcp_vol_ctlr_discover(&fixture->conns[i], &vol_ctlr);
655 		zassert_equal(0, err, "Unexpected return value %d", err);
656 	}
657 
658 	err = bt_cap_commander_change_volume_mute_state(&param);
659 	zassert_equal(-EINVAL, err, "Unexpected return value %d", err);
660 }
661 
ZTEST_F(cap_commander_test_vcp,test_commander_change_volume_mute_state_inval_missing_vcs)662 ZTEST_F(cap_commander_test_vcp, test_commander_change_volume_mute_state_inval_missing_vcs)
663 {
664 	union bt_cap_set_member members[ARRAY_SIZE(fixture->conns)];
665 	const struct bt_cap_commander_change_volume_mute_state_param param = {
666 		.type = BT_CAP_SET_TYPE_AD_HOC,
667 		.members = members,
668 		.count = ARRAY_SIZE(fixture->conns),
669 		.mute = true,
670 	};
671 	int err;
672 
673 	for (size_t i = 0U; i < ARRAY_SIZE(members); i++) {
674 		members[i].member = &fixture->conns[i];
675 	}
676 
677 	err = bt_cap_commander_register_cb(&mock_cap_commander_cb);
678 	zassert_equal(0, err, "Unexpected return value %d", err);
679 
680 	err = bt_cap_commander_change_volume_mute_state(&param);
681 	zassert_equal(-EINVAL, err, "Unexpected return value %d", err);
682 }
683 
ZTEST_F(cap_commander_test_vcp,test_commander_change_volume_mute_state_inval_param_zero_count)684 ZTEST_F(cap_commander_test_vcp, test_commander_change_volume_mute_state_inval_param_zero_count)
685 {
686 	union bt_cap_set_member members[ARRAY_SIZE(fixture->conns)];
687 	const struct bt_cap_commander_change_volume_mute_state_param param = {
688 		.type = BT_CAP_SET_TYPE_AD_HOC,
689 		.members = members,
690 		.count = 0U,
691 		.mute = true,
692 	};
693 	int err;
694 
695 	for (size_t i = 0U; i < ARRAY_SIZE(members); i++) {
696 		members[i].member = &fixture->conns[i];
697 	}
698 
699 	err = bt_cap_commander_change_volume_mute_state(&param);
700 	zassert_equal(-EINVAL, err, "Unexpected return value %d", err);
701 }
702 
ZTEST_F(cap_commander_test_vcp,test_commander_change_volume_mute_state_inval_param_inval_count)703 ZTEST_F(cap_commander_test_vcp, test_commander_change_volume_mute_state_inval_param_inval_count)
704 {
705 	union bt_cap_set_member members[ARRAY_SIZE(fixture->conns)];
706 	const struct bt_cap_commander_change_volume_mute_state_param param = {
707 		.type = BT_CAP_SET_TYPE_AD_HOC,
708 		.members = members,
709 		.count = CONFIG_BT_MAX_CONN + 1,
710 		.mute = true,
711 	};
712 	int err;
713 
714 	for (size_t i = 0U; i < ARRAY_SIZE(members); i++) {
715 		members[i].member = &fixture->conns[i];
716 	}
717 
718 	err = bt_cap_commander_change_volume_mute_state(&param);
719 	zassert_equal(-EINVAL, err, "Unexpected return value %d", err);
720 }
721