1 /*
2 * Copyright (C) 2025 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include <gmock/gmock.h>
17 #include <gtest/gtest.h>
18
19 #include "bluetooth_log.h"
20 #include "napi_event_subscribe_module.h"
21
22 using namespace testing;
23 using namespace testing::ext;
24
25 static size_t g_napiGetCbInfoArgc = 0;
NapiGetCbInfoMockSetArgc(size_t argc)26 void NapiGetCbInfoMockSetArgc(size_t argc)
27 {
28 g_napiGetCbInfoArgc = argc;
29 }
napi_get_cb_info(napi_env env,napi_callback_info cbinfo,size_t * argc,napi_value * argv,napi_value * this_arg,void ** data)30 napi_status napi_get_cb_info(napi_env env, napi_callback_info cbinfo, size_t* argc, napi_value* argv,
31 napi_value* this_arg, void** data)
32 {
33 *argc = g_napiGetCbInfoArgc;
34 return napi_ok;
35 }
napi_close_handle_scope(napi_env env,napi_handle_scope scope)36 napi_status napi_close_handle_scope(napi_env env, napi_handle_scope scope)
37 {
38 return napi_ok;
39 }
40
41 namespace OHOS {
42 namespace Bluetooth {
43 void NapiMockClear(void);
44
45 class NapiEventSubscribeModuleTest : public testing::Test {
46 public:
47 NapiEventSubscribeModuleTest() = default;
48 ~NapiEventSubscribeModuleTest() = default;
49
SetUpTestSuite(void)50 static void SetUpTestSuite(void) {}
TearDownTestSuite(void)51 static void TearDownTestSuite(void) {}
SetUp()52 void SetUp()
53 {
54 NapiMockClear();
55 }
TearDown()56 void TearDown() {}
57
58 napi_env env_;
59 napi_callback_info info_;
60 };
61
62 static std::string g_napiParseStringStr = "";
63 static bool g_napiParseStringIsString = false;
64
NapiParseStringMock(std::string str,bool isString)65 void NapiParseStringMock(std::string str, bool isString)
66 {
67 g_napiParseStringStr = str;
68 g_napiParseStringIsString = isString;
69 }
70
NapiParseString(napi_env env,napi_value value,std::string & outStr)71 napi_status NapiParseString(napi_env env, napi_value value, std::string &outStr)
72 {
73 outStr = g_napiParseStringStr;
74 return g_napiParseStringIsString ? napi_ok : napi_invalid_arg;
75 }
76
77 static bool g_napiIsFunction = false;
78
NapiIsFunctionMock(bool isFunction)79 napi_status NapiIsFunctionMock(bool isFunction)
80 {
81 g_napiIsFunction = isFunction;
82 return napi_ok;
83 }
84
NapiIsFunction(napi_env env,napi_value value)85 napi_status NapiIsFunction(napi_env env, napi_value value)
86 {
87 return g_napiIsFunction ? napi_ok : napi_invalid_arg;
88 }
89
NapiCallback(napi_env env,napi_value callback)90 NapiCallback::NapiCallback(napi_env env, napi_value callback) {}
~NapiCallback()91 NapiCallback::~NapiCallback() {}
92
93 static int g_napiCallFunctionCount = 0;
CallFunction(const std::shared_ptr<NapiNativeObject> & object)94 void NapiCallback::CallFunction(const std::shared_ptr<NapiNativeObject> &object)
95 {
96 g_napiCallFunctionCount++;
97 }
CallFunction(int errCode,const std::shared_ptr<NapiNativeObject> & object)98 void NapiCallback::CallFunction(int errCode, const std::shared_ptr<NapiNativeObject> &object) {}
GetNapiEnv(void)99 napi_env NapiCallback::GetNapiEnv(void)
100 {
101 return env_;
102 }
ToLogString(void) const103 std::string NapiCallback::ToLogString(void) const
104 {
105 return "";
106 }
107
108 static bool g_napiCallbackIsEqual = false;
NapiCallbackIsEqualMock(bool equal)109 void NapiCallbackIsEqualMock(bool equal)
110 {
111 g_napiCallbackIsEqual = equal;
112 }
Equal(napi_env env,napi_value & callback) const113 bool NapiCallback::Equal(napi_env env, napi_value &callback) const
114 {
115 return g_napiCallbackIsEqual;
116 }
117
DoInJsMainThread(std::function<void (void)> func)118 int DoInJsMainThread(std::function<void(void)> func)
119 {
120 func();
121 return 0;
122 }
123
DoInJsMainThread(napi_env env,std::function<void (void)> func)124 int DoInJsMainThread(napi_env env, std::function<void(void)> func)
125 {
126 func();
127 return 0;
128 }
129
NapiMockClear(void)130 void NapiMockClear(void)
131 {
132 g_napiGetCbInfoArgc = 0;
133 g_napiParseStringStr = "";
134 g_napiParseStringIsString = false;
135 g_napiIsFunction = false;
136 g_napiCallbackIsEqual = false;
137 g_napiCallFunctionCount = 0;
138 }
139
140 static const char * const TEST_CALLBACK_NAME = "testCallback";
141
142 /**
143 * @tc.name: NapiEventSubscribeModuleTest_001
144 * @tc.desc: Test register and deregister normal
145 * @tc.type: FUNC
146 */
147 HWTEST_F(NapiEventSubscribeModuleTest, NapiEventSubscribeModuleTest_001, TestSize.Level0)
148 {
149 HILOGI("NapiEventSubscribeModuleTest_001 enter");
150 NapiEventSubscribeModule subscribe(TEST_CALLBACK_NAME, "testModule");
151
152 NapiGetCbInfoMockSetArgc(2);
153 NapiParseStringMock(TEST_CALLBACK_NAME, true);
154
155 NapiIsFunctionMock(true);
156 NapiCallbackIsEqualMock(false);
157
158 napi_status ret = subscribe.Register(env_, info_);
159 EXPECT_EQ(ret, napi_ok);
160 EXPECT_EQ(subscribe.eventSubscribeMap_.ReadVal(TEST_CALLBACK_NAME).size(), 1);
161
162 NapiGetCbInfoMockSetArgc(2);
163 NapiParseStringMock(TEST_CALLBACK_NAME, true);
164
165 NapiIsFunctionMock(true);
166 NapiCallbackIsEqualMock(true);
167
168 ret = subscribe.Deregister(env_, info_);
169 EXPECT_EQ(ret, napi_ok);
170 EXPECT_EQ(subscribe.eventSubscribeMap_.ReadVal(TEST_CALLBACK_NAME).size(), 0);
171
172 HILOGI("NapiEventSubscribeModuleTest_001 end");
173 }
174
175 /**
176 * @tc.name: NapiEventSubscribeModuleTest_002
177 * @tc.desc: Test register the type callback, and the same callback Repeated
178 * @tc.type: FUNC
179 */
180 HWTEST_F(NapiEventSubscribeModuleTest, NapiEventSubscribeModuleTest_002, TestSize.Level0)
181 {
182 HILOGI("NapiEventSubscribeModuleTest_002 enter");
183 NapiEventSubscribeModule subscribe(TEST_CALLBACK_NAME, "testModule");
184
185 NapiGetCbInfoMockSetArgc(2);
186 NapiParseStringMock(TEST_CALLBACK_NAME, true);
187
188 NapiIsFunctionMock(true);
189 NapiCallbackIsEqualMock(false);
190
191 napi_status ret = subscribe.Register(env_, info_);
192 EXPECT_EQ(ret, napi_ok);
193 EXPECT_EQ(subscribe.eventSubscribeMap_.ReadVal(TEST_CALLBACK_NAME).size(), 1);
194
195 // Mock the same callback
196 NapiCallbackIsEqualMock(true);
197 ret = subscribe.Register(env_, info_);
198 EXPECT_EQ(ret, napi_ok);
199 EXPECT_EQ(subscribe.eventSubscribeMap_.ReadVal(TEST_CALLBACK_NAME).size(), 1);
200
201 HILOGI("NapiEventSubscribeModuleTest_002 end");
202 }
203
204 /**
205 * @tc.name: NapiEventSubscribeModuleTest_003
206 * @tc.desc: Test register the type callback, and multi callback
207 * @tc.type: FUNC
208 */
209 HWTEST_F(NapiEventSubscribeModuleTest, NapiEventSubscribeModuleTest_003, TestSize.Level0)
210 {
211 HILOGI("NapiEventSubscribeModuleTest_003 enter");
212 NapiEventSubscribeModule subscribe(TEST_CALLBACK_NAME, "testModule");
213
214 NapiGetCbInfoMockSetArgc(2);
215 NapiParseStringMock(TEST_CALLBACK_NAME, true);
216
217 NapiIsFunctionMock(true);
218 NapiCallbackIsEqualMock(false);
219
220 napi_status ret = subscribe.Register(env_, info_);
221 EXPECT_EQ(ret, napi_ok);
222 EXPECT_EQ(subscribe.eventSubscribeMap_.ReadVal(TEST_CALLBACK_NAME).size(), 1);
223
224 ret = subscribe.Register(env_, info_);
225 EXPECT_EQ(ret, napi_ok);
226 EXPECT_EQ(subscribe.eventSubscribeMap_.ReadVal(TEST_CALLBACK_NAME).size(), 2);
227
228 HILOGI("NapiEventSubscribeModuleTest_003 end");
229 }
230
231 /**
232 * @tc.name: NapiEventSubscribeModuleTest_004
233 * @tc.desc: Test publish event
234 * @tc.type: FUNC
235 */
236 HWTEST_F(NapiEventSubscribeModuleTest, NapiEventSubscribeModuleTest_004, TestSize.Level0)
237 {
238 HILOGI("NapiEventSubscribeModuleTest_004 enter");
239 NapiEventSubscribeModule subscribe(TEST_CALLBACK_NAME, "testModule");
240
241 NapiGetCbInfoMockSetArgc(2);
242 NapiParseStringMock(TEST_CALLBACK_NAME, true);
243
244 NapiIsFunctionMock(true);
245 NapiCallbackIsEqualMock(false);
246
247 napi_status ret = subscribe.Register(env_, info_);
248 EXPECT_EQ(ret, napi_ok);
249 EXPECT_EQ(subscribe.eventSubscribeMap_.ReadVal(TEST_CALLBACK_NAME).size(), 1);
250
251 subscribe.PublishEvent(TEST_CALLBACK_NAME, nullptr);
252 EXPECT_EQ(g_napiCallFunctionCount, 1);
253
254 HILOGI("NapiEventSubscribeModuleTest_004 end");
255 }
256
257 /**
258 * @tc.name: NapiEventSubscribeModuleTest_005
259 * @tc.desc: Test register failed
260 * @tc.type: FUNC
261 */
262 HWTEST_F(NapiEventSubscribeModuleTest, NapiEventSubscribeModuleTest_005, TestSize.Level0)
263 {
264 HILOGI("NapiEventSubscribeModuleTest_005 enter");
265 NapiEventSubscribeModule subscribe(TEST_CALLBACK_NAME, "testModule");
266
267 // Invalid params size
268 NapiGetCbInfoMockSetArgc(1);
269 napi_status ret = subscribe.Register(env_, info_);
270 EXPECT_EQ(ret, napi_invalid_arg);
271
272 // Invalid argv[0] string type
273 NapiGetCbInfoMockSetArgc(2);
274 NapiParseStringMock(TEST_CALLBACK_NAME, false);
275 ret = subscribe.Register(env_, info_);
276 EXPECT_EQ(ret, napi_invalid_arg);
277
278 // Invalid type name
279 NapiGetCbInfoMockSetArgc(2);
280 NapiParseStringMock("errCallbackName", true);
281 ret = subscribe.Register(env_, info_);
282 EXPECT_EQ(ret, napi_invalid_arg);
283
284 // Invalid argv[1] function type
285 NapiGetCbInfoMockSetArgc(2);
286 NapiParseStringMock(TEST_CALLBACK_NAME, true);
287 NapiIsFunctionMock(false);
288 ret = subscribe.Register(env_, info_);
289 EXPECT_EQ(ret, napi_invalid_arg);
290
291 HILOGI("NapiEventSubscribeModuleTest_005 end");
292 }
293
294 /**
295 * @tc.name: NapiEventSubscribeModuleTest_006
296 * @tc.desc: Test register failed
297 * @tc.type: FUNC
298 */
299 HWTEST_F(NapiEventSubscribeModuleTest, NapiEventSubscribeModuleTest_006, TestSize.Level0)
300 {
301 HILOGI("NapiEventSubscribeModuleTest_006 enter");
302 NapiEventSubscribeModule subscribe(TEST_CALLBACK_NAME, "testModule");
303
304 // Invalid params size
305 NapiGetCbInfoMockSetArgc(3);
306 napi_status ret = subscribe.Deregister(env_, info_);
307 EXPECT_EQ(ret, napi_invalid_arg);
308
309 NapiGetCbInfoMockSetArgc(0);
310 ret = subscribe.Deregister(env_, info_);
311 EXPECT_EQ(ret, napi_invalid_arg);
312
313 // Invalid argv[0] string type
314 NapiGetCbInfoMockSetArgc(2);
315 NapiParseStringMock(TEST_CALLBACK_NAME, false);
316 ret = subscribe.Deregister(env_, info_);
317 EXPECT_EQ(ret, napi_invalid_arg);
318
319 // Invalid type name
320 NapiGetCbInfoMockSetArgc(2);
321 NapiParseStringMock("errCallbackName", true);
322 ret = subscribe.Deregister(env_, info_);
323 EXPECT_EQ(ret, napi_invalid_arg);
324
325 // Invalid argv[1] function type
326 NapiGetCbInfoMockSetArgc(2);
327 NapiParseStringMock(TEST_CALLBACK_NAME, true);
328 NapiIsFunctionMock(false);
329 ret = subscribe.Register(env_, info_);
330 EXPECT_EQ(ret, napi_invalid_arg);
331
332 // The callback is not registered
333 NapiGetCbInfoMockSetArgc(2);
334 NapiParseStringMock(TEST_CALLBACK_NAME, true);
335 NapiIsFunctionMock(true);
336 NapiCallbackIsEqualMock(true);
337 ret = subscribe.Deregister(env_, info_);
338 EXPECT_EQ(ret, napi_ok);
339
340 HILOGI("NapiEventSubscribeModuleTest_006 end");
341 }
342
343 /**
344 * @tc.name: NapiEventSubscribeModuleTest_007
345 * @tc.desc: Test publish event failed
346 * @tc.type: FUNC
347 */
348 HWTEST_F(NapiEventSubscribeModuleTest, NapiEventSubscribeModuleTest_007, TestSize.Level0)
349 {
350 HILOGI("NapiEventSubscribeModuleTest_007 enter");
351 NapiEventSubscribeModule subscribe(TEST_CALLBACK_NAME, "testModule");
352
353 // Invalid eventName
354 NapiGetCbInfoMockSetArgc(2);
355 NapiParseStringMock(TEST_CALLBACK_NAME, true);
356
357 NapiIsFunctionMock(true);
358 NapiCallbackIsEqualMock(false);
359
360 napi_status ret = subscribe.Register(env_, info_);
361 EXPECT_EQ(ret, napi_ok);
362 EXPECT_EQ(subscribe.eventSubscribeMap_.ReadVal(TEST_CALLBACK_NAME).size(), 1);
363
364 subscribe.PublishEvent("errCallbackName", nullptr);
365 EXPECT_EQ(g_napiCallFunctionCount, 0);
366
367 // Empty callback in map
368 NapiGetCbInfoMockSetArgc(2);
369 NapiParseStringMock(TEST_CALLBACK_NAME, true);
370
371 NapiIsFunctionMock(true);
372 NapiCallbackIsEqualMock(true);
373
374 ret = subscribe.Deregister(env_, info_);
375 EXPECT_EQ(ret, napi_ok);
376 EXPECT_EQ(subscribe.eventSubscribeMap_.ReadVal(TEST_CALLBACK_NAME).size(), 0);
377
378 subscribe.PublishEvent(TEST_CALLBACK_NAME, nullptr);
379 EXPECT_EQ(g_napiCallFunctionCount, 0);
380
381 HILOGI("NapiEventSubscribeModuleTest_007 end");
382 }
383
384 /**
385 * @tc.name: NapiEventSubscribeModuleTest_008
386 * @tc.desc: Test Deregister all callback
387 * @tc.type: FUNC
388 */
389 HWTEST_F(NapiEventSubscribeModuleTest, NapiEventSubscribeModuleTest_008, TestSize.Level0)
390 {
391 HILOGI("NapiEventSubscribeModuleTest_008 enter");
392 NapiEventSubscribeModule subscribe(TEST_CALLBACK_NAME, "testModule");
393
394 NapiGetCbInfoMockSetArgc(2);
395 NapiParseStringMock(TEST_CALLBACK_NAME, true);
396
397 NapiIsFunctionMock(true);
398 NapiCallbackIsEqualMock(false);
399
400 napi_status ret = subscribe.Register(env_, info_);
401 EXPECT_EQ(ret, napi_ok);
402 EXPECT_EQ(subscribe.eventSubscribeMap_.ReadVal(TEST_CALLBACK_NAME).size(), 1);
403
404 ret = subscribe.Register(env_, info_);
405 EXPECT_EQ(ret, napi_ok);
406 EXPECT_EQ(subscribe.eventSubscribeMap_.ReadVal(TEST_CALLBACK_NAME).size(), 2);
407
408 NapiGetCbInfoMockSetArgc(1);
409 NapiParseStringMock(TEST_CALLBACK_NAME, true);
410
411 ret = subscribe.Deregister(env_, info_);
412 EXPECT_EQ(ret, napi_ok);
413 EXPECT_EQ(subscribe.eventSubscribeMap_.ReadVal(TEST_CALLBACK_NAME).size(), 0);
414
415 HILOGI("NapiEventSubscribeModuleTest_008 end");
416 }
417
418 /**
419 * @tc.name: NapiEventSubscribeModuleTest_009
420 * @tc.desc: Test publish a event with multi callback
421 * @tc.type: FUNC
422 */
423 HWTEST_F(NapiEventSubscribeModuleTest, NapiEventSubscribeModuleTest_009, TestSize.Level0)
424 {
425 HILOGI("NapiEventSubscribeModuleTest_009 enter");
426 napi_env env;
427 napi_value callback = nullptr;
428 NapiEventSubscribeModule subscribe(TEST_CALLBACK_NAME, "testModule");
429
__anonfd7c0eef0102(auto & callbackVec) 430 subscribe.eventSubscribeMap_.ChangeValueByLambda(TEST_CALLBACK_NAME, [env, callback](auto & callbackVec) {
431 auto napiCallback = std::make_shared<NapiCallback>(env, callback);
432 callbackVec.push_back(napiCallback);
433 napiCallback = std::make_shared<NapiCallback>(env, callback);
434 callbackVec.push_back(napiCallback);
435 });
436
437 subscribe.PublishEvent(TEST_CALLBACK_NAME, nullptr);
438 EXPECT_EQ(g_napiCallFunctionCount, 2);
439
440 HILOGI("NapiEventSubscribeModuleTest_009 end");
441 }
442 } // namespace Bluetooth
443 } // namespace OHOS