Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / chrome / utility / media_galleries / iphoto_library_parser_unittest.cc
blob7fb0fc7b92c5b52af546729fe9d6e902aba7ed0c
1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "base/logging.h"
6 #include "chrome/common/media_galleries/iphoto_library.h"
7 #include "chrome/utility/media_galleries/iphoto_library_parser.h"
8 #include "testing/gtest/include/gtest/gtest.h"
10 #define SIMPLE_HEADER() \
11 "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" \
12 "<plist version=\"1.0\">" \
13 " <dict>" \
14 " <key>Archive Path</key>" \
15 " <string>/Users/username/px</string>"
17 #define ALBUMS_HEADER() \
18 " <key>List of Albums</key>" \
19 " <array>"
21 #define ALBUMS_FOOTER() \
22 " </array>"
24 #define SIMPLE_ALBUM(id, name, photo1, photo2) \
25 " <dict>" \
26 " <key>AlbumId</key>" \
27 " <integer>" #id "</integer>" \
28 " <key>AlbumName</key>" \
29 " <string>" name "</string>" \
30 " <key>KeyList</key>" \
31 " <array>" \
32 " <string>" #photo1 "</string>" \
33 " <string>" #photo2 "</string>" \
34 " </array>" \
35 " </dict>"
37 #define IMAGE_LIST_HEADER() \
38 " <key>Master Image List</key>" \
39 " <dict>"
41 #define IMAGE_LIST_FOOTER() \
42 " </dict>"
44 #define SIMPLE_PHOTO(id, guid, path, caption) \
45 " <key>" #id "</key>" \
46 " <dict>" \
47 " <key>MediaType</key>" \
48 " <string>Image</string>" \
49 " <key>Caption</key>" \
50 " <string>" caption "</string>" \
51 " <key>GUID</key>" \
52 " <string>" #guid "</string>" \
53 " <key>ModDateAsTimerInterval</key>" \
54 " <string>386221543.0000</string>" \
55 " <key>DateAsTimerInterval</key>" \
56 " <string>386221543.0000</string>" \
57 " <key>DateAsTimerIntervalGMT</key>" \
58 " <string>385123456.00</string>" \
59 " <key>ImagePath</key>" \
60 " <string>" path "</string>" \
61 " <key>OriginalPath</key>" \
62 " <string>/original" path "</string>" \
63 " <key>ThumbPath</key>" \
64 " <string>" path "</string>" \
65 " </dict>"
67 #define SIMPLE_FOOTER() \
68 " </dict>" \
69 "</plist>"
71 // Mismatched key/string tag at ImagePath.
72 #define MALFORMED_PHOTO1(id, guid, path, caption) \
73 " <key>" #id "</key>" \
74 " <dict>" \
75 " <key>MediaType</key>" \
76 " <string>Image</string>" \
77 " <key>Caption<key>" \
78 " <string>" caption "</string>" \
79 " <key>GUID</key>" \
80 " <string>" #guid "</string>" \
81 " <key>ImagePath</string>" \
82 " <string>" path "</string>" \
83 " <key>ThumbPath</key>" \
84 " <string>" path "</string>" \
85 " </dict>"
87 // Missing "<" delimiter at ImagePath.
88 #define MALFORMED_PHOTO2(id, guid, path, caption) \
89 " <key>" #id "</key>" \
90 " <dict>" \
91 " <key>MediaType</key>" \
92 " <string>Image</string>" \
93 " <key>Caption<key>" \
94 " <string>" caption "</string>" \
95 " <key>GUID</key>" \
96 " <string>" #guid "</string>" \
97 " <key>ImagePath/key>" \
98 " <string>" path "</string>" \
99 " <key>ThumbPath</key>" \
100 " <string>" path "</string>" \
101 " </dict>"
103 namespace iphoto {
105 namespace {
107 void ComparePhoto(const parser::Photo& a, const parser::Photo& b) {
108 EXPECT_EQ(a.id, b.id);
109 EXPECT_EQ(a.location.value(), b.location.value());
110 EXPECT_EQ(a.original_location.value(), b.original_location.value());
113 void CompareAlbum(const parser::Album& a, const parser::Album& b) {
114 EXPECT_EQ(a.size(), b.size());
116 parser::Album::const_iterator a_it;
117 parser::Album::const_iterator b_it;
118 for (a_it = a.begin(), b_it = b.begin();
119 a_it != a.end() && b_it != b.end();
120 ++a_it, ++b_it) {
121 EXPECT_EQ(*a_it, *b_it);
125 void CompareAlbums(const parser::Albums& a, const parser::Albums& b) {
126 EXPECT_EQ(a.size(), b.size());
128 parser::Albums::const_iterator a_it;
129 parser::Albums::const_iterator b_it;
130 for (a_it = a.begin(), b_it = b.begin();
131 a_it != a.end() && b_it != b.end();
132 ++a_it, ++b_it) {
133 EXPECT_EQ(a_it->first, b_it->first);
134 CompareAlbum(a_it->second, b_it->second);
138 void CompareLibrary(const parser::Library& a, const parser::Library& b) {
139 CompareAlbums(a.albums, b.albums);
141 std::set<parser::Photo>::const_iterator a_it;
142 std::set<parser::Photo>::const_iterator b_it;
143 for (a_it = a.all_photos.begin(), b_it = b.all_photos.begin();
144 a_it != a.all_photos.end() && b_it != b.all_photos.end();
145 ++a_it, ++b_it) {
146 ComparePhoto(*a_it, *b_it);
150 class IPhotoLibraryParserTest : public testing::Test {
151 public:
152 IPhotoLibraryParserTest() {}
154 void TestParser(bool expected_result, const std::string& xml) {
155 IPhotoLibraryParser parser;
157 EXPECT_EQ(expected_result, parser.Parse(xml));
158 if (!expected_result)
159 return;
161 CompareLibrary(expected_library_, parser.library());
164 void AddExpectedPhoto(uint32 id,
165 const std::string& location,
166 const std::string& album) {
167 parser::Photo photo(id, base::FilePath::FromUTF8Unsafe(location),
168 base::FilePath::FromUTF8Unsafe("/original" + location));
169 if (!album.empty())
170 expected_library_.albums[album].insert(id);
171 expected_library_.all_photos.insert(photo);
174 private:
175 parser::Library expected_library_;
177 DISALLOW_COPY_AND_ASSIGN(IPhotoLibraryParserTest);
180 TEST_F(IPhotoLibraryParserTest, EmptyLibrary) {
181 TestParser(false, "");
184 TEST_F(IPhotoLibraryParserTest, MinimalXML) {
185 AddExpectedPhoto(1, "/dir/Photo With Space.jpg", "");
186 TestParser(
187 true,
188 SIMPLE_HEADER()
189 IMAGE_LIST_HEADER()
190 SIMPLE_PHOTO(1, 1, "/dir/Photo With Space.jpg", "Photo 1")
191 IMAGE_LIST_FOOTER()
192 SIMPLE_FOOTER());
195 TEST_F(IPhotoLibraryParserTest, MultiplePhotos) {
196 AddExpectedPhoto(1, "/dir/SongA1.jpg", "");
197 AddExpectedPhoto(2, "/dir/SongA2.jpg", "");
198 AddExpectedPhoto(3, "/dir/SongA3.jpg", "");
199 AddExpectedPhoto(4, "/dir/SongB1.jpg", "");
200 AddExpectedPhoto(5, "/dir/SongB2.jpg", "");
201 AddExpectedPhoto(6, "/dir2/SongB1.jpg", "");
202 AddExpectedPhoto(7, "/dir2/SongB2.jpg", "");
203 TestParser(
204 true,
205 SIMPLE_HEADER()
206 IMAGE_LIST_HEADER()
207 SIMPLE_PHOTO(1, 1, "/dir/SongA1.jpg", "Photo 1")
208 SIMPLE_PHOTO(2, 2, "/dir/SongA2.jpg", "Photo 2")
209 SIMPLE_PHOTO(3, 3, "/dir/SongA3.jpg", "Photo 3")
210 SIMPLE_PHOTO(4, 4, "/dir/SongB1.jpg", "Photo 4")
211 SIMPLE_PHOTO(5, 5, "/dir/SongB2.jpg", "Photo 5")
212 SIMPLE_PHOTO(6, 6, "/dir2/SongB1.jpg", "Photo 6")
213 SIMPLE_PHOTO(7, 7, "/dir2/SongB2.jpg", "Photo 7")
214 IMAGE_LIST_FOOTER()
215 SIMPLE_FOOTER());
218 TEST_F(IPhotoLibraryParserTest, Albums) {
219 AddExpectedPhoto(1, "/dir/PhotoA1.jpg", "Album 1");
220 AddExpectedPhoto(2, "/dir/PhotoA2.jpg", "Album 1");
221 AddExpectedPhoto(3, "/dir/PhotoA3.jpg", "Album 2");
222 AddExpectedPhoto(4, "/dir/PhotoB1.jpg", "Album 2");
223 AddExpectedPhoto(5, "/dir/PhotoB2.jpg", "Album 3");
224 AddExpectedPhoto(6, "/dir2/PhotoB1.jpg", "Album 3");
225 AddExpectedPhoto(7, "/dir2/PhotoB2.jpg", "");
226 TestParser(
227 true,
228 SIMPLE_HEADER()
229 ALBUMS_HEADER()
230 SIMPLE_ALBUM(10, "Album 1", 1, 2)
231 SIMPLE_ALBUM(11, "Album 2", 3, 4)
232 SIMPLE_ALBUM(11, "Album/3", 5, 6)
233 ALBUMS_FOOTER()
234 IMAGE_LIST_HEADER()
235 SIMPLE_PHOTO(1, 1, "/dir/PhotoA1.jpg", "Photo 1")
236 SIMPLE_PHOTO(2, 2, "/dir/PhotoA2.jpg", "Photo 2")
237 SIMPLE_PHOTO(3, 3, "/dir/PhotoA3.jpg", "Photo 3")
238 SIMPLE_PHOTO(4, 4, "/dir/PhotoB1.jpg", "Photo 4")
239 SIMPLE_PHOTO(5, 5, "/dir/PhotoB2.jpg", "Photo 5")
240 SIMPLE_PHOTO(6, 6, "/dir2/PhotoB1.jpg", "Photo 6")
241 SIMPLE_PHOTO(7, 7, "/dir2/PhotoB2.jpg", "Photo 7")
242 IMAGE_LIST_FOOTER()
243 SIMPLE_FOOTER());
246 TEST_F(IPhotoLibraryParserTest, MalformedStructure) {
247 TestParser(
248 false,
249 SIMPLE_HEADER()
250 ALBUMS_HEADER()
251 ALBUMS_HEADER()
252 ALBUMS_FOOTER()
253 SIMPLE_FOOTER());
255 TestParser(
256 false,
257 SIMPLE_HEADER()
258 ALBUMS_HEADER()
259 ALBUMS_FOOTER()
260 IMAGE_LIST_HEADER()
261 IMAGE_LIST_HEADER()
262 SIMPLE_PHOTO(1, 1, "/bad.jpg", "p1")
263 IMAGE_LIST_FOOTER()
264 IMAGE_LIST_FOOTER()
265 SIMPLE_FOOTER());
267 TestParser(
268 false,
269 SIMPLE_HEADER()
270 ALBUMS_HEADER()
271 ALBUMS_FOOTER()
272 IMAGE_LIST_HEADER()
273 ALBUMS_HEADER()
274 SIMPLE_PHOTO(1, 1, "/bad.jpg", "p1")
275 IMAGE_LIST_FOOTER()
276 SIMPLE_FOOTER());
279 TEST_F(IPhotoLibraryParserTest, MalformedSyntax) {
280 TestParser(
281 false,
282 SIMPLE_HEADER()
283 ALBUMS_HEADER()
284 ALBUMS_FOOTER()
285 IMAGE_LIST_HEADER()
286 MALFORMED_PHOTO1(1, 1, "/bad.jpg", "p1")
287 IMAGE_LIST_FOOTER()
288 SIMPLE_FOOTER());
290 TestParser(
291 false,
292 SIMPLE_HEADER()
293 ALBUMS_HEADER()
294 ALBUMS_FOOTER()
295 IMAGE_LIST_HEADER()
296 MALFORMED_PHOTO2(1, 1, "/bad.jpg", "p1")
297 IMAGE_LIST_FOOTER()
298 SIMPLE_FOOTER());
301 TEST_F(IPhotoLibraryParserTest, DuplicateAlbumNames) {
302 AddExpectedPhoto(1, "/dir/PhotoA1.jpg", "Album 1");
303 AddExpectedPhoto(2, "/dir/PhotoA2.jpg", "Album 1");
304 AddExpectedPhoto(3, "/dir/PhotoA3.jpg", "Album 1(11)");
305 AddExpectedPhoto(4, "/dir/PhotoB1.jpg", "Album 1(11)");
306 TestParser(
307 true,
308 SIMPLE_HEADER()
309 ALBUMS_HEADER()
310 SIMPLE_ALBUM(10, "Album 1", 1, 2)
311 SIMPLE_ALBUM(11, "Album 1", 3, 4)
312 ALBUMS_FOOTER()
313 IMAGE_LIST_HEADER()
314 SIMPLE_PHOTO(1, 1, "/dir/PhotoA1.jpg", "Photo 1")
315 SIMPLE_PHOTO(2, 2, "/dir/PhotoA2.jpg", "Photo 2")
316 SIMPLE_PHOTO(3, 3, "/dir/PhotoA3.jpg", "Photo 3")
317 SIMPLE_PHOTO(4, 4, "/dir/PhotoB1.jpg", "Photo 4")
318 IMAGE_LIST_FOOTER()
319 SIMPLE_FOOTER());
322 } // namespace
324 } // namespace iphoto