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