1 /*
2 * Copyright (C) 2023 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 #include "medialibrary_command.h"
16 #define MLOG_TAG "PhotoAlbumTest"
17
18 #include "photo_album_test.h"
19
20 #include "fetch_result.h"
21 #include "media_file_utils.h"
22 #include "media_log.h"
23 #include "medialibrary_album_operations.h"
24 #include "medialibrary_data_manager.h"
25 #include "medialibrary_db_const.h"
26 #include "medialibrary_errno.h"
27 #include "medialibrary_rdbstore.h"
28 #include "medialibrary_unittest_utils.h"
29 #include "photo_album_column.h"
30 #include "photo_map_column.h"
31 #include "rdb_predicates.h"
32 #include "result_set_utils.h"
33 #include "medialibrary_unistore_manager.h"
34
35 namespace OHOS::Media {
36 using namespace std;
37 using namespace testing::ext;
38 using namespace OHOS::NativeRdb;
39 using namespace OHOS::DataShare;
40 using OHOS::DataShare::DataShareValuesBucket;
41 using OHOS::DataShare::DataSharePredicates;
42
43 static shared_ptr<MediaLibraryRdbStore> g_rdbStore;
44 const std::string URI_CREATE_PHOTO_ALBUM = MEDIALIBRARY_DATA_URI + "/" + PHOTO_ALBUM_OPRN + "/" + OPRN_CREATE;
45 const std::string URI_UPDATE_PHOTO_ALBUM = MEDIALIBRARY_DATA_URI + "/" + PHOTO_ALBUM_OPRN + "/" + OPRN_UPDATE;
46 const std::string URI_ORDER_ALBUM = MEDIALIBRARY_DATA_URI + "/" + PHOTO_ALBUM_OPRN + "/" + OPRN_ORDER_ALBUM;
ClearTable(const string & table)47 int32_t ClearTable(const string &table)
48 {
49 RdbPredicates predicates(table);
50
51 int32_t rows = 0;
52 int32_t err = g_rdbStore->Delete(rows, predicates);
53 if (err != E_OK) {
54 MEDIA_ERR_LOG("Failed to clear album table, err: %{public}d", err);
55 return E_HAS_DB_ERROR;
56 }
57 return E_OK;
58 }
59
ClearUserAlbums()60 int32_t ClearUserAlbums()
61 {
62 RdbPredicates predicates(PhotoAlbumColumns::TABLE);
63 predicates.EqualTo(PhotoAlbumColumns::ALBUM_TYPE, to_string(PhotoAlbumType::USER));
64
65 int32_t rows = 0;
66 int32_t err = g_rdbStore->Delete(rows, predicates);
67 if (err != E_OK) {
68 MEDIA_ERR_LOG("Failed to clear album table, err: %{public}d", err);
69 return E_HAS_DB_ERROR;
70 }
71 return E_OK;
72 }
73
CheckColumn(shared_ptr<OHOS::NativeRdb::ResultSet> & resultSet,const string & column,ResultSetDataType type,const variant<int32_t,string,int64_t,double> & expected)74 inline void CheckColumn(shared_ptr<OHOS::NativeRdb::ResultSet> &resultSet, const string &column,
75 ResultSetDataType type, const variant<int32_t, string, int64_t, double> &expected)
76 {
77 EXPECT_EQ(ResultSetUtils::GetValFromColumn(column, resultSet, type), expected);
78 }
79
CreatePhotoAlbum(const string & albumName)80 inline int32_t CreatePhotoAlbum(const string &albumName)
81 {
82 DataShareValuesBucket values;
83 values.Put(PhotoAlbumColumns::ALBUM_NAME, albumName);
84 Uri uri(URI_CREATE_PHOTO_ALBUM);
85 MediaLibraryCommand cmd(uri);
86 return MediaLibraryDataManager::GetInstance()->Insert(cmd, values);
87 }
88
DeletePhotoAlbum(DataSharePredicates & predicates)89 inline int32_t DeletePhotoAlbum(DataSharePredicates &predicates)
90 {
91 Uri uri(URI_CREATE_PHOTO_ALBUM);
92 MediaLibraryCommand cmd(uri, OperationType::DELETE);
93 return MediaLibraryDataManager::GetInstance()->Delete(cmd, predicates);
94 }
95
GetLastDentry(const string & path)96 inline string GetLastDentry(const string &path)
97 {
98 string dentry = path;
99 size_t slashIndex = path.rfind('/');
100 if (slashIndex != string::npos) {
101 dentry = path.substr(slashIndex + 1);
102 }
103 return dentry;
104 }
105
DoCheckAlbumData(const string & name,const bool isRelativePath)106 void DoCheckAlbumData(const string &name, const bool isRelativePath)
107 {
108 string albumName = isRelativePath ? GetLastDentry(name) : name;
109 string relativePath = isRelativePath ? name : "";
110
111 RdbPredicates predicates(PhotoAlbumColumns::TABLE);
112 predicates.EqualTo(PhotoAlbumColumns::ALBUM_NAME, albumName);
113 if (isRelativePath) {
114 predicates.EqualTo(PhotoAlbumColumns::ALBUM_RELATIVE_PATH, relativePath);
115 } else {
116 predicates.IsNull(PhotoAlbumColumns::ALBUM_RELATIVE_PATH);
117 }
118
119 const vector<string> columns = {
120 PhotoAlbumColumns::ALBUM_ID,
121 PhotoAlbumColumns::ALBUM_TYPE,
122 PhotoAlbumColumns::ALBUM_SUBTYPE,
123 PhotoAlbumColumns::ALBUM_NAME,
124 PhotoAlbumColumns::ALBUM_COVER_URI,
125 PhotoAlbumColumns::ALBUM_COUNT,
126 PhotoAlbumColumns::ALBUM_RELATIVE_PATH,
127 PhotoAlbumColumns::ALBUM_IMAGE_COUNT,
128 PhotoAlbumColumns::ALBUM_VIDEO_COUNT,
129 };
130
131 shared_ptr<OHOS::NativeRdb::ResultSet> resultSet = g_rdbStore->Query(predicates, columns);
132 ASSERT_NE(resultSet, nullptr);
133
134 int32_t count = -1;
135 int32_t ret = resultSet->GetRowCount(count);
136 CHECK_AND_RETURN_LOG(ret == E_OK, "Failed to get count! err: %{public}d", ret);
137 MEDIA_INFO_LOG("Query count: %{public}d", count);
138 ret = resultSet->GoToFirstRow();
139 CHECK_AND_RETURN_LOG(ret == E_OK, "Failed to GoToFirstRow! err: %{public}d", ret);
140
141 int32_t albumId = get<int32_t>(ResultSetUtils::GetValFromColumn(PhotoAlbumColumns::ALBUM_ID, resultSet,
142 TYPE_INT32));
143 EXPECT_GT(albumId, 0);
144 CheckColumn(resultSet, PhotoAlbumColumns::ALBUM_TYPE, TYPE_INT32, PhotoAlbumType::USER);
145 CheckColumn(resultSet, PhotoAlbumColumns::ALBUM_SUBTYPE, TYPE_INT32, PhotoAlbumSubType::USER_GENERIC);
146 CheckColumn(resultSet, PhotoAlbumColumns::ALBUM_NAME, TYPE_STRING, albumName);
147 CheckColumn(resultSet, PhotoAlbumColumns::ALBUM_COVER_URI, TYPE_STRING, "");
148 CheckColumn(resultSet, PhotoAlbumColumns::ALBUM_COUNT, TYPE_INT32, 0);
149 CheckColumn(resultSet, PhotoAlbumColumns::ALBUM_RELATIVE_PATH, TYPE_STRING, relativePath);
150 CheckColumn(resultSet, PhotoAlbumColumns::ALBUM_IMAGE_COUNT, TYPE_INT32, 0);
151 CheckColumn(resultSet, PhotoAlbumColumns::ALBUM_VIDEO_COUNT, TYPE_INT32, 0);
152 }
153
CheckAlbumData(const string & albumName)154 inline void CheckAlbumData(const string &albumName)
155 {
156 DoCheckAlbumData(albumName, false);
157 }
158
CreatePhotoAlbumAndCheck(const string & albumName)159 inline void CreatePhotoAlbumAndCheck(const string &albumName)
160 {
161 MEDIA_INFO_LOG("Creating album with albumName: %{public}s", albumName.c_str());
162 EXPECT_GT(CreatePhotoAlbum(albumName), 0);
163 CheckAlbumData(albumName);
164 }
165
QueryAlbumById(int32_t id,string & albumName,string & cover)166 int32_t QueryAlbumById(int32_t id, string &albumName, string &cover)
167 {
168 RdbPredicates predicates(PhotoAlbumColumns::TABLE);
169 predicates.EqualTo(PhotoAlbumColumns::ALBUM_ID, to_string(id));
170 auto resultSet = g_rdbStore->Query(predicates, { });
171 EXPECT_NE(resultSet, nullptr);
172 if (resultSet == nullptr) {
173 return E_HAS_DB_ERROR;
174 }
175
176 int32_t count = -1;
177 CHECK_AND_RETURN_RET(resultSet->GetRowCount(count) == E_OK, E_HAS_DB_ERROR);
178 MEDIA_INFO_LOG("Query count: %{public}d", count);
179 CHECK_AND_RETURN_RET(resultSet->GoToFirstRow() == E_OK, E_HAS_DB_ERROR);
180 albumName = get<string>(ResultSetUtils::GetValFromColumn(PhotoAlbumColumns::ALBUM_NAME, resultSet, TYPE_STRING));
181 cover = get<string>(ResultSetUtils::GetValFromColumn(PhotoAlbumColumns::ALBUM_COVER_URI, resultSet, TYPE_STRING));
182 return E_OK;
183 }
184
UpdatePhotoAlbum(const DataShareValuesBucket & values,const DataSharePredicates & predicates)185 inline int32_t UpdatePhotoAlbum(const DataShareValuesBucket &values, const DataSharePredicates &predicates)
186 {
187 Uri uri(URI_UPDATE_PHOTO_ALBUM);
188 MediaLibraryCommand cmd(uri, OperationType::UPDATE);
189 return MediaLibraryDataManager::GetInstance()->Update(cmd, values, predicates);
190 }
191
OrderAlbums(const DataShareValuesBucket & values,const DataSharePredicates & predicates)192 inline int32_t OrderAlbums(const DataShareValuesBucket &values, const DataSharePredicates &predicates)
193 {
194 Uri uri(URI_ORDER_ALBUM);
195 MediaLibraryCommand cmd(uri, OperationType::ALBUM_ORDER);
196 return MediaLibraryDataManager::GetInstance()->Update(cmd, values, predicates);
197 }
198
CheckUpdatedAlbum(int32_t albumId,const string & expectedName,const string & expectedCover)199 void CheckUpdatedAlbum(int32_t albumId, const string &expectedName, const string &expectedCover)
200 {
201 string coverUri;
202 string albumName;
203 int32_t ret = QueryAlbumById(albumId, albumName, coverUri);
204 if (ret < 0) {
205 return;
206 }
207 EXPECT_EQ(albumName, expectedName);
208 EXPECT_EQ(coverUri, expectedCover);
209 }
210
CheckUpdatedSystemAlbum(PhotoAlbumSubType subType,const string & expectedName,const string & expectedCover)211 void CheckUpdatedSystemAlbum(PhotoAlbumSubType subType, const string &expectedName, const string &expectedCover)
212 {
213 RdbPredicates predicates(PhotoAlbumColumns::TABLE);
214 predicates.EqualTo(PhotoAlbumColumns::ALBUM_TYPE, to_string(PhotoAlbumType::SYSTEM));
215 predicates.EqualTo(PhotoAlbumColumns::ALBUM_SUBTYPE, to_string(subType));
216
217 const vector<string> columns = {
218 PhotoAlbumColumns::ALBUM_NAME,
219 PhotoAlbumColumns::ALBUM_COVER_URI,
220 };
221
222 auto resultSet = g_rdbStore->Query(predicates, columns);
223 ASSERT_NE(resultSet, nullptr);
224 int32_t count = -1;
225 CHECK_AND_RETURN_LOG(resultSet->GetRowCount(count) == E_OK, "Failed to get count!");
226 MEDIA_INFO_LOG("Query count: %{public}d", count);
227 CHECK_AND_RETURN_LOG(resultSet->GoToFirstRow() == E_OK, "Failed to GoToFirstRow!");
228 string albumName = get<string>(ResultSetUtils::GetValFromColumn(PhotoAlbumColumns::ALBUM_NAME, resultSet,
229 TYPE_STRING));
230 string cover = get<string>(ResultSetUtils::GetValFromColumn(PhotoAlbumColumns::ALBUM_COVER_URI, resultSet,
231 TYPE_STRING));
232 EXPECT_EQ(albumName, expectedName);
233 EXPECT_EQ(cover, expectedCover);
234 }
235
GetAlbumOrder(int32_t albumId)236 int32_t GetAlbumOrder(int32_t albumId)
237 {
238 RdbPredicates predicates(PhotoAlbumColumns::TABLE);
239 predicates.EqualTo(PhotoAlbumColumns::ALBUM_ID, to_string(albumId));
240 auto resultSet = g_rdbStore->Query(predicates, { });
241 EXPECT_NE(resultSet, nullptr);
242 if (resultSet == nullptr) {
243 return E_HAS_DB_ERROR;
244 }
245
246 int32_t count = -1;
247 CHECK_AND_RETURN_RET(resultSet->GetRowCount(count) == E_OK, E_HAS_DB_ERROR);
248 MEDIA_INFO_LOG("Query count: %{public}d", count);
249 CHECK_AND_RETURN_RET(resultSet->GoToFirstRow() == E_OK, E_HAS_DB_ERROR);
250 int32_t albumOrder = get<int32_t>(ResultSetUtils::GetValFromColumn(PhotoAlbumColumns::ALBUM_ORDER,
251 resultSet, TYPE_INT32));
252 EXPECT_GT(albumOrder, 0);
253 return albumOrder;
254 }
255
GetMaxAlbumOrder(int32_t & maxAlbumOrder)256 void GetMaxAlbumOrder(int32_t &maxAlbumOrder)
257 {
258 RdbPredicates predicates(PhotoAlbumColumns::TABLE);
259 auto resultSet = g_rdbStore->Query(predicates, { "Max(album_order)" });
260 int32_t ret = resultSet->GoToFirstRow();
261 CHECK_AND_RETURN_LOG(ret == E_OK, "Failed to GoToFirstRow! err: %{public}d", ret);
262 resultSet->GetInt(0, maxAlbumOrder);
263 }
264
SetUpTestCase()265 void PhotoAlbumTest::SetUpTestCase()
266 {
267 MediaLibraryUnitTestUtils::Init();
268 g_rdbStore = MediaLibraryUnistoreManager::GetInstance().GetRdbStore();
269 ClearUserAlbums();
270 ClearTable(PhotoMap::TABLE);
271 }
272
TearDownTestCase()273 void PhotoAlbumTest::TearDownTestCase() {}
274
275 // SetUp:Execute before each test case
SetUp()276 void PhotoAlbumTest::SetUp() {}
277
TearDown()278 void PhotoAlbumTest::TearDown() {}
279
280 /**
281 * @tc.name: photoalbum_create_album_001
282 * @tc.desc: Create photo albums test
283 * 1. Create an album called "photoalbum_create_album_001"
284 * @tc.type: FUNC
285 * @tc.require: issueI6B1SE
286 */
287 HWTEST_F(PhotoAlbumTest, photoalbum_create_album_001, TestSize.Level0)
288 {
289 MEDIA_INFO_LOG("photoalbum_create_album_001 enter");
290 CreatePhotoAlbumAndCheck("photoalbum_create_album_001");
291 MEDIA_INFO_LOG("photoalbum_create_album_001 exit");
292 }
293
294 /**
295 * @tc.name: photoalbum_create_album_002
296 * @tc.desc: Create photo albums test
297 * 1. Create an album with special characters
298 * @tc.type: FUNC
299 * @tc.require: issueI6B1SE
300 */
301 HWTEST_F(PhotoAlbumTest, photoalbum_create_album_002, TestSize.Level0)
302 {
303 MEDIA_INFO_LOG("photoalbum_create_album_002 enter");
304 string albumName = "photoalbum_create_album_002";
305 const static string ALBUM_NAME_REGEX = R"([\.\\/:*?"'`<>|{}\[\]])";
306 for (const auto &ch : ALBUM_NAME_REGEX) {
307 albumName.append(1, ch);
308 EXPECT_EQ(CreatePhotoAlbum(albumName), -EINVAL);
309 albumName.pop_back();
310 }
311 MEDIA_INFO_LOG("photoalbum_create_album_002 exit");
312 }
313
314 /**
315 * @tc.name: photoalbum_create_album_003
316 * @tc.desc: Create an album which name contains dot
317 * 1. Create an album with a leading dot
318 * 2. Create an album end with a dot
319 * 3. Create an album contains dot in the middle way
320 * 4. Create an album with two leading dots
321 * 5. Create an album contains two dots in the middle way
322 * @tc.type: FUNC
323 * @tc.require: issueI6B1SE
324 */
325 HWTEST_F(PhotoAlbumTest, photoalbum_create_album_003, TestSize.Level0)
326 {
327 MEDIA_INFO_LOG("photoalbum_create_album_003 enter");
328 const vector<string> testAlbumNames = {
329 ".photoalbum_create_album_003",
330 "photoalbum_create_album_003.",
331 "photoalbum_.create_album_003",
332 "..photoalbum_create_album_003",
333 "photoalbum_.create._album_003"
334 };
335
336 for (const auto &albumName : testAlbumNames) {
337 MEDIA_INFO_LOG("Creating album: %{public}s", albumName.c_str());
338 EXPECT_EQ(CreatePhotoAlbum(albumName), -EINVAL);
339 }
340 MEDIA_INFO_LOG("photoalbum_create_album_003 exit");
341 }
342
343 /**
344 * @tc.name: photoalbum_create_album_004
345 * @tc.desc: Create photo albums test
346 * 1. Create albums with several super long names
347 * 2. Create an album with an empty name
348 * @tc.type: FUNC
349 * @tc.require: issueI6B1SE
350 */
351 HWTEST_F(PhotoAlbumTest, photoalbum_create_album_004, TestSize.Level0)
352 {
353 MEDIA_INFO_LOG("photoalbum_create_album_004 enter");
354 constexpr size_t displayNameMax = 255;
355 string albumName(displayNameMax, 'a');
356 CreatePhotoAlbumAndCheck(albumName);
357 albumName.resize(0);
358 albumName.resize(displayNameMax - 1, 'b');
359 CreatePhotoAlbumAndCheck(albumName);
360 albumName.resize(0);
361 albumName.resize(displayNameMax + 1, 'c');
362 EXPECT_EQ(CreatePhotoAlbum(albumName), -ENAMETOOLONG);
363 albumName.resize(0);
364 EXPECT_EQ(CreatePhotoAlbum(albumName), -EINVAL);
365 MEDIA_INFO_LOG("photoalbum_create_album_004 exit");
366 }
367
368 /**
369 * @tc.name: photoalbum_create_album_005
370 * @tc.desc: Create an existed album
371 * @tc.type: FUNC
372 * @tc.require: issueI6B1SE
373 */
374 HWTEST_F(PhotoAlbumTest, photoalbum_create_album_005, TestSize.Level0)
375 {
376 MEDIA_INFO_LOG("photoalbum_create_album_005 enter");
377 const string albumName = "photoalbum_create_album_005";
378 CreatePhotoAlbumAndCheck(albumName);
379 EXPECT_EQ(CreatePhotoAlbum(albumName), -1);
380 EXPECT_EQ(CreatePhotoAlbum(albumName), -1);
381 EXPECT_EQ(CreatePhotoAlbum(albumName), -1);
382 MEDIA_INFO_LOG("photoalbum_create_album_005 exit");
383 }
384
385 /**
386 * @tc.name: photoalbum_create_album_006
387 * @tc.desc: Create an mark album
388 * @tc.type: FUNC
389 * @tc.require: issueI97YYD
390 */
391 HWTEST_F(PhotoAlbumTest, photoalbum_create_album_006, TestSize.Level0)
392 {
393 MEDIA_INFO_LOG("photoalbum_create_album_006 enter");
394 const string albumName = "photoalbum_create_album_006";
395 DataShareValuesBucket values;
396 values.Put(PhotoAlbumColumns::ALBUM_NAME, albumName);
397 values.Put(PhotoAlbumColumns::ALBUM_IS_LOCAL, 1);
398 Uri uri(URI_CREATE_PHOTO_ALBUM);
399 MediaLibraryCommand cmd(uri);
400 int32_t result = MediaLibraryDataManager::GetInstance()->Insert(cmd, values);
401 EXPECT_GT(result, 0);
402
403 RdbPredicates predicates(PhotoAlbumColumns::TABLE);
404 predicates.EqualTo(PhotoAlbumColumns::ALBUM_NAME, albumName);
405 predicates.EqualTo(PhotoAlbumColumns::ALBUM_IS_LOCAL, 1);
406
407 const vector<string> columns = {
408 PhotoAlbumColumns::ALBUM_NAME,
409 PhotoAlbumColumns::ALBUM_IS_LOCAL,
410 };
411
412 shared_ptr<OHOS::NativeRdb::ResultSet> resultSet = g_rdbStore->Query(predicates, columns);
413 int32_t count = -1;
414 int32_t ret = resultSet->GetRowCount(count);
415 CHECK_AND_RETURN_LOG(ret == E_OK, "Failed to get count! err: %{public}d", ret);
416 MEDIA_INFO_LOG("Query count: %{public}d", count);
417 ret = resultSet->GoToFirstRow();
418 CHECK_AND_RETURN_LOG(ret == E_OK, "Failed to GoToFirstRow! err: %{public}d", ret);
419 CheckColumn(resultSet, PhotoAlbumColumns::ALBUM_IS_LOCAL, TYPE_INT32, 1);
420 MEDIA_INFO_LOG("photoalbum_create_album_006 exit");
421 }
422
423 /**
424 * @tc.name: photoalbum_create_album_007
425 * @tc.desc: Create an album with the same album name as the existed deleted album
426 * @tc.type: FUNC
427 * @tc.require: issueI9KEDW
428 */
429 HWTEST_F(PhotoAlbumTest, photoalbum_create_album_007, TestSize.Level0)
430 {
431 MEDIA_INFO_LOG("photoalbum_create_album_007 enter");
432 const string albumName = "photoalbum_create_album_007";
433 string insertSql = "INSERT INTO " + PhotoAlbumColumns::TABLE + " (" + PhotoAlbumColumns::ALBUM_TYPE + ", " +
434 PhotoAlbumColumns::ALBUM_SUBTYPE + ", " + PhotoAlbumColumns::ALBUM_NAME + ", " +
435 PhotoAlbumColumns::ALBUM_DIRTY + ") VALUES (" + to_string(static_cast<int32_t>(PhotoAlbumType::USER)) + ", " +
436 to_string(static_cast<int32_t>(PhotoAlbumSubType::USER_GENERIC)) + ", '" + albumName + "', " +
437 to_string(static_cast<int32_t>(DirtyTypes::TYPE_DELETED)) + ")";
438 int32_t insertRet = g_rdbStore->ExecuteSql(insertSql);
439 ASSERT_EQ(insertRet, E_OK);
440
441 RdbPredicates predicates(PhotoAlbumColumns::TABLE);
442 predicates.EqualTo(PhotoAlbumColumns::ALBUM_NAME, albumName);
443 const vector<string> columns = { PhotoAlbumColumns::ALBUM_ID, PhotoAlbumColumns::ALBUM_TYPE,
444 PhotoAlbumColumns::ALBUM_SUBTYPE, PhotoAlbumColumns::ALBUM_COUNT, PhotoAlbumColumns::ALBUM_DIRTY };
445 shared_ptr<OHOS::NativeRdb::ResultSet> resultSet = g_rdbStore->Query(predicates, columns);
446 ASSERT_NE(resultSet, nullptr);
447 int32_t count = -1;
448 int32_t ret = resultSet->GetRowCount(count);
449 CHECK_AND_RETURN_LOG(ret == E_OK, "Failed to get count! err: %{public}d", ret);
450 MEDIA_INFO_LOG("Query count: %{public}d", count);
451 EXPECT_GT(count, 0);
452 ret = resultSet->GoToFirstRow();
453 CHECK_AND_RETURN_LOG(ret == E_OK, "Failed to GoToFirstRow! err: %{public}d", ret);
454
455 int32_t albumId = get<int32_t>(ResultSetUtils::GetValFromColumn(PhotoAlbumColumns::ALBUM_ID, resultSet,
456 TYPE_INT32));
457 EXPECT_GT(albumId, 0);
458 CheckColumn(resultSet, PhotoAlbumColumns::ALBUM_TYPE, TYPE_INT32, PhotoAlbumType::USER);
459 CheckColumn(resultSet, PhotoAlbumColumns::ALBUM_SUBTYPE, TYPE_INT32, PhotoAlbumSubType::USER_GENERIC);
460 CheckColumn(resultSet, PhotoAlbumColumns::ALBUM_COUNT, TYPE_INT32, 0);
461 CheckColumn(resultSet, PhotoAlbumColumns::ALBUM_DIRTY, TYPE_INT32, static_cast<int32_t>(DirtyTypes::TYPE_DELETED));
462
463 EXPECT_GT(CreatePhotoAlbum(albumName), 0); // creation succeeded for the first time
464 EXPECT_EQ(CreatePhotoAlbum(albumName), -1); // creation failed because of the newly created album
465 EXPECT_EQ(CreatePhotoAlbum(albumName), -1); // creation failed because of the newly created album
466 MEDIA_INFO_LOG("photoalbum_create_album_007 exit");
467 }
468
469 /**
470 * @tc.name: photoalbum_delete_album_001
471 * @tc.desc: Delete a photo album.
472 * 1. Create an album and then delete it.
473 * @tc.type: FUNC
474 * @tc.require: issueI6O6FE
475 */
476 HWTEST_F(PhotoAlbumTest, photoalbum_delete_album_001, TestSize.Level0)
477 {
478 MEDIA_INFO_LOG("photoalbum_delete_album_001 enter");
479
480 const vector<string> albumNames = {
481 "photoalbum_delete_album_001_001",
482 "photoalbum_delete_album_001_002",
483 "photoalbum_delete_album_001_003",
484 "photoalbum_delete_album_001_004",
485 "photoalbum_delete_album_001_005",
486 };
487
488 vector<string> albumIds;
489 for (const auto &albumName : albumNames) {
490 int32_t albumId = CreatePhotoAlbum(albumName);
491 ASSERT_GT(albumId, 0);
492 albumIds.push_back(to_string(albumId));
493 }
494 DataSharePredicates predicates;
495 predicates.In(PhotoAlbumColumns::ALBUM_ID, albumIds);
496 EXPECT_EQ(DeletePhotoAlbum(predicates), albumNames.size());
497 MEDIA_INFO_LOG("photoalbum_delete_album_001 end");
498 }
499
500 /**
501 * @tc.name: photoalbum_delete_album_001
502 * @tc.desc: Update photo album info.
503 * 1. Rename an album
504 * @tc.type: FUNC
505 * @tc.require: issueI6P7NG
506 */
507 HWTEST_F(PhotoAlbumTest, photoalbum_update_album_001, TestSize.Level0)
508 {
509 MEDIA_INFO_LOG("photoalbum_update_album_001 enter");
510 const string albumName = "photoalbum_update_album_001";
511 int32_t albumId = CreatePhotoAlbum(albumName);
512 ASSERT_GT(albumId, 0);
513
514 DataSharePredicates predicates;
515 predicates.EqualTo(PhotoAlbumColumns::ALBUM_ID, albumId);
516 DataShareValuesBucket values;
517 const string newName = "NewAlbumName1";
518 const string newCover = "file://media/asset/10";
519 values.Put(PhotoAlbumColumns::ALBUM_NAME, newName);
520 values.Put(PhotoAlbumColumns::ALBUM_COVER_URI, newCover);
521 constexpr int32_t changedRows = 1;
522 EXPECT_EQ(UpdatePhotoAlbum(values, predicates), changedRows);
523 CheckUpdatedAlbum(albumId, newName, "");
524
525 MEDIA_INFO_LOG("photoalbum_update_album_001 end");
526 }
527
528 /**
529 * @tc.name: photoalbum_delete_album_002
530 * @tc.desc: Update photo album info.
531 * 1. Update coverUri
532 * @tc.type: FUNC
533 * @tc.require: issueI6P7NG
534 */
535 HWTEST_F(PhotoAlbumTest, photoalbum_update_album_002, TestSize.Level0)
536 {
537 MEDIA_INFO_LOG("photoalbum_update_album_002 enter");
538 const string albumName = "photoalbum_update_album_002";
539 int32_t albumId = CreatePhotoAlbum(albumName);
540 ASSERT_GT(albumId, 0);
541
542 DataSharePredicates predicates;
543 predicates.EqualTo(PhotoAlbumColumns::ALBUM_ID, albumId);
544 DataShareValuesBucket values;
545 const string newCover = "file://media/asset/10";
546 values.Put(PhotoAlbumColumns::ALBUM_COVER_URI, newCover);
547 constexpr int32_t changedRows = 1;
548 EXPECT_EQ(UpdatePhotoAlbum(values, predicates), changedRows);
549 CheckUpdatedAlbum(albumId, albumName, newCover);
550
551 MEDIA_INFO_LOG("photoalbum_update_album_002 end");
552 }
553
554 /**
555 * @tc.name: photoalbum_update_album_004
556 * @tc.desc: Update photo album info.
557 * 1. Update albumName and coverUri
558 * @tc.type: FUNC
559 * @tc.require: issueI6P7NG
560 */
561 HWTEST_F(PhotoAlbumTest, photoalbum_update_album_003, TestSize.Level0)
562 {
563 MEDIA_INFO_LOG("photoalbum_update_album_003 enter");
564 const string albumName = "photoalbum_update_album_003";
565 int32_t albumId = CreatePhotoAlbum(albumName);
566 ASSERT_GT(albumId, 0);
567
568 // Build value buckets
569 const string newName = "NewAlbumName3";
570 const string newCover = "file://media/asset/10";
571 DataShareValuesBucket values;
572 values.Put(PhotoAlbumColumns::ALBUM_NAME, newName);
573 values.Put(PhotoAlbumColumns::ALBUM_COVER_URI, newCover);
574
575 // Build predicates
576 DataSharePredicates predicates;
577 predicates.EqualTo(PhotoAlbumColumns::ALBUM_ID, albumId);
578 constexpr int32_t changedRows = 1;
579 EXPECT_EQ(UpdatePhotoAlbum(values, predicates), changedRows);
580 CheckUpdatedAlbum(albumId, newName, newCover);
581
582 MEDIA_INFO_LOG("photoalbum_update_album_003 end");
583 }
584
585 /**
586 * @tc.name: photoalbum_update_album_004
587 * @tc.desc: Update photo album info.
588 * 1. Update with empty values, this should return an error.
589 * @tc.type: FUNC
590 * @tc.require: issueI6P7NG
591 */
592 HWTEST_F(PhotoAlbumTest, photoalbum_update_album_004, TestSize.Level0)
593 {
594 MEDIA_INFO_LOG("photoalbum_update_album_004 enter");
595 const string albumName = "photoalbum_update_album_004";
596 int32_t albumId = CreatePhotoAlbum(albumName);
597 ASSERT_GT(albumId, 0);
598
599 // Build empty values
600 DataShareValuesBucket values;
601
602 // Build predicates
603 DataSharePredicates predicates;
604 predicates.EqualTo(PhotoAlbumColumns::ALBUM_ID, albumId);
605 EXPECT_EQ(UpdatePhotoAlbum(values, predicates), E_INVALID_VALUES);
606 CheckUpdatedAlbum(albumId, albumName, "");
607
608 MEDIA_INFO_LOG("photoalbum_update_album_004 end");
609 }
610
611 /**
612 * @tc.name: photoalbum_order_album_006
613 * @tc.desc: order photo album.
614 * move current album before reference album
615 * @tc.type: FUNC
616 * @tc.require: issueI6P7NG
617 */
618 HWTEST_F(PhotoAlbumTest, photoalbum_order_album_006, TestSize.Level0)
619 {
620 MEDIA_INFO_LOG("photoalbum_order_album_006 enter");
621
622 // Build empty values
623 DataShareValuesBucket values;
624 values.Put(PhotoAlbumColumns::ALBUM_ID, 2);
625 values.Put(PhotoAlbumColumns::REFERENCE_ALBUM_ID, 5); // 2\5:album_id
626 // Try to update favorite system
627 DataSharePredicates predicates;
628 EXPECT_EQ(OrderAlbums(values, predicates), 0);
629 int32_t currentOrder = GetAlbumOrder(2);
630 MEDIA_INFO_LOG("current order is %{public}d", currentOrder);
631 int32_t referenceOrder = GetAlbumOrder(5);
632 MEDIA_INFO_LOG("reference order is %{public}d", referenceOrder);
633 EXPECT_LT(currentOrder, referenceOrder);
634 MEDIA_INFO_LOG("photoalbum_order_album_006 end");
635 }
636
637 /**
638 * @tc.name: photoalbum_order_album_007
639 * @tc.desc: repeat order same photo album, to see if order deranged.
640 * move current album before reference album
641 * @tc.type: FUNC
642 * @tc.require: issueI6P7NG
643 */
644 HWTEST_F(PhotoAlbumTest, photoalbum_order_album_007, TestSize.Level0)
645 {
646 MEDIA_INFO_LOG("photoalbum_order_album_007 enter");
647
648 // Build empty values
649 DataShareValuesBucket values;
650 values.Put(PhotoAlbumColumns::ALBUM_ID, 2); // 2\5:album_id
651 values.Put(PhotoAlbumColumns::REFERENCE_ALBUM_ID, 5);
652 // Try to update favorite system
653 DataSharePredicates predicates;
654 EXPECT_EQ(OrderAlbums(values, predicates), 0);
655 int32_t currentOrder = GetAlbumOrder(2);
656 MEDIA_INFO_LOG("current order is %{public}d", currentOrder);
657 int32_t referenceOrder = GetAlbumOrder(5);
658 MEDIA_INFO_LOG("reference order is %{public}d", referenceOrder);
659 EXPECT_LT(currentOrder, referenceOrder);
660 MEDIA_INFO_LOG("photoalbum_order_album_007 end");
661 }
662
663 /**
664 * @tc.name: photoalbum_order_album_008
665 * @tc.desc: order photo album, move the album to the end.
666 * move current album before reference album
667 * @tc.type: FUNC
668 * @tc.require: issueI6P7NG
669 */
670 HWTEST_F(PhotoAlbumTest, photoalbum_order_album_008, TestSize.Level0)
671 {
672 MEDIA_INFO_LOG("photoalbum_order_album_008 enter");
673
674 // Build empty values
675 DataShareValuesBucket values;
676 values.Put(PhotoAlbumColumns::ALBUM_ID, 3); // 3:album_id
677 values.Put(PhotoAlbumColumns::REFERENCE_ALBUM_ID, -1);
678 // Try to update favorite system
679 DataSharePredicates predicates;
680 EXPECT_EQ(OrderAlbums(values, predicates), 0);
681 int32_t currentOrder = GetAlbumOrder(3);
682 int32_t maxAlbumOrder = -1;
683 GetMaxAlbumOrder(maxAlbumOrder);
684 EXPECT_EQ(currentOrder, maxAlbumOrder);
685 MEDIA_INFO_LOG("photoalbum_order_album_008 end");
686 }
687
688 /**
689 * @tc.name: photoalbum_order_album_009
690 * @tc.desc: order photo album, move the album to the end.
691 * move current album before reference album
692 * @tc.type: FUNC
693 * @tc.require: issueI6P7NG
694 */
695 HWTEST_F(PhotoAlbumTest, photoalbum_order_album_009, TestSize.Level0)
696 {
697 MEDIA_INFO_LOG("photoalbum_order_album_009 enter");
698
699 // Build empty values
700 DataShareValuesBucket values;
701 values.Put(PhotoAlbumColumns::ALBUM_ID, 5); // 5\2: album_id
702 values.Put(PhotoAlbumColumns::REFERENCE_ALBUM_ID, 2);
703 // Try to update favorite system
704 DataSharePredicates predicates;
705 EXPECT_EQ(OrderAlbums(values, predicates), 0);
706 int32_t currentOrder = GetAlbumOrder(2);
707 int32_t referenceOrder = GetAlbumOrder(5);
708 EXPECT_GT(currentOrder, referenceOrder);
709 MEDIA_INFO_LOG("photoalbum_order_album_009 end");
710 }
711 } // namespace OHOS::Media
712