Folders.cpp 10.6 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
/*****************************************************************************
 * Media Library
 *****************************************************************************
 * Copyright (C) 2015 Hugo Beauzée-Luyssen, Videolabs
 *
 * Authors: Hugo Beauzée-Luyssen<hugo@beauzee.fr>
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation; either version 2.1 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
 *****************************************************************************/

23
#include "Tests.h"
24

25
#include "Media.h"
26
27
#include "IFolder.h"
#include "IMediaLibrary.h"
28
#include "Utils.h"
29
#include "mocks/FileSystem.h"
30
#include "mocks/DiscovererCbMock.h"
31
32

#include <memory>
33

34
class Folders : public Tests
35
{
36
    protected:
37
        std::shared_ptr<mock::FileSystemFactory> fsMock;
38
        std::unique_ptr<mock::WaitForDiscoveryComplete> cbMock;
39
40

    protected:
41
        virtual void SetUp() override
42
43
        {
            fsMock.reset( new mock::FileSystemFactory );
44
45
            cbMock.reset( new mock::WaitForDiscoveryComplete );
            Reload();
46
47
        }

48
        virtual void Reload()
49
        {
50
            Tests::Reload( fsMock, cbMock.get() );
51
        }
52
};
53
54
55

TEST_F( Folders, Add )
{
56
    cbMock->prepareForWait( 1 );
57
    ml->discover( "." );
58
59
    bool discovered = cbMock->wait();
    ASSERT_TRUE( discovered );
60

61
    auto files = ml->files();
62

63
    ASSERT_EQ( files.size(), 3u );
64
    ASSERT_FALSE( std::static_pointer_cast<Media>( files[0] )->isStandAlone() );
65
66
67
68
}

TEST_F( Folders, Delete )
{
69
    cbMock->prepareForWait( 1 );
70
    ml->discover( "." );
71
72
    bool discovered = cbMock->wait();
    ASSERT_TRUE( discovered );
73

74
    auto f = ml->folder( mock::FileSystemFactory::Root );
75
76
    auto folderPath = f->path();

77
    auto files = ml->files();
78
    ASSERT_EQ( files.size(), 3u );
79

80
81
    auto filePath = files[0]->mrl();

82
83
    ml->deleteFolder( f );

84
85
86
    f = ml->folder( folderPath );
    ASSERT_EQ( nullptr, f );

87
    files = ml->files();
88
    ASSERT_EQ( files.size(), 0u );
89
90
91
92
93

    // Check the file isn't cached anymore:
    auto file = ml->file( filePath );
    ASSERT_EQ( nullptr, file );

94
    cbMock->prepareForReload();
95
    Reload();
96
97
    bool reloaded = cbMock->waitForReload();
    ASSERT_TRUE( reloaded );
98
99
100
101

    // Recheck folder deletion from DB:
    f = ml->folder( folderPath );
    ASSERT_EQ( nullptr, f );
102
103
104
105
}

TEST_F( Folders, Load )
{
106
    cbMock->prepareForWait( 1 );
107
    ml->discover( "." );
108
109
    bool discovered = cbMock->wait();
    ASSERT_TRUE( discovered );
110

111
    cbMock->prepareForReload();
112
    Reload();
113
114
    bool reloaded = cbMock->waitForReload();
    ASSERT_TRUE( reloaded );
115

116
117
118
    auto files = ml->files();
    ASSERT_EQ( files.size(), 3u );
    for ( auto& f : files )
119
        ASSERT_FALSE( std::static_pointer_cast<Media>( f )->isStandAlone() );
120
}
121
122
123

TEST_F( Folders, InvalidPath )
{
124
    cbMock->prepareForWait( 1 );
125
    ml->discover( "/invalid/path" );
126
127
    bool discovered = cbMock->wait();
    ASSERT_TRUE( discovered );
128

129
    auto files = ml->files();
130
131
    ASSERT_EQ( files.size(), 0u );
}
132
133
134

TEST_F( Folders, List )
{
135
    cbMock->prepareForWait( 1 );
136
    ml->discover( "." );
137
138
    bool discovered = cbMock->wait();
    ASSERT_TRUE( discovered );
139

140
    auto f = ml->folder( mock::FileSystemFactory::Root );
141
    ASSERT_NE( f, nullptr );
142
143
144
    auto files = f->files();
    ASSERT_EQ( files.size(), 2u );

145
    cbMock->prepareForReload();
146
    Reload();
147
148
    bool reloaded = cbMock->waitForReload();
    ASSERT_TRUE( reloaded );
149
150
151
152
153

    f = ml->folder( f->path() );
    files = f->files();
    ASSERT_EQ( files.size(), 2u );
}
154
155
156

TEST_F( Folders, AbsolutePath )
{
157
    cbMock->prepareForWait( 1 );
158
    ml->discover( "." );
159
160
161
    bool discovered = cbMock->wait();
    ASSERT_TRUE( discovered );

162
163
    auto f = ml->folder( "." );
    ASSERT_EQ( f, nullptr );
164
}
165
166
167

TEST_F( Folders, ListFolders )
{
168
    cbMock->prepareForWait( 1 );
169
    ml->discover( "." );
170
171
172
    bool discovered = cbMock->wait();
    ASSERT_TRUE( discovered );

173
    auto f = ml->folder( mock::FileSystemFactory::Root );
174
    ASSERT_NE( f, nullptr );
175
176
177
178
179
180
181
182
183
184
    auto subFolders = f->folders();
    ASSERT_EQ( 1u, subFolders.size() );

    auto subFolder = subFolders[0];
    auto subFiles = subFolder->files();
    ASSERT_EQ( 1u, subFiles.size() );

    auto file = subFiles[0];
    ASSERT_EQ( std::string{ mock::FileSystemFactory::SubFolder } + "subfile.mp4", file->mrl() );

185
    // Now again, without cache. No need to wait for fs discovery reload here
186
    Reload();
187
188
189
190
191
192
193
194
195
196
197
198

    f = ml->folder( f->path() );
    subFolders = f->folders();
    ASSERT_EQ( 1u, subFolders.size() );

    subFolder = subFolders[0];
    subFiles = subFolder->files();
    ASSERT_EQ( 1u, subFiles.size() );

    file = subFiles[0];
    ASSERT_EQ( std::string{ mock::FileSystemFactory::SubFolder } + "subfile.mp4", file->mrl() );
}
199
200
201

TEST_F( Folders, LastModificationDate )
{
202
    cbMock->prepareForWait( 1 );
203
    ml->discover( "." );
204
205
206
    bool discovered = cbMock->wait();
    ASSERT_TRUE( discovered );

207
    auto f = ml->folder( mock::FileSystemFactory::Root );
208
    ASSERT_NE( 0u, f->lastModificationDate() );
209
    auto subFolders = f->folders();
210
    ASSERT_NE( 0u, subFolders[0]->lastModificationDate() );
211

212
    Reload();
213
214

    f = ml->folder( f->path() );
215
    ASSERT_NE( 0u, f->lastModificationDate() );
216
    subFolders = f->folders();
217
    ASSERT_NE( 0u, subFolders[0]->lastModificationDate() );
218
}
219

220
TEST_F( Folders, NewFolderWithFile )
221
{
222
    cbMock->prepareForWait( 1 );
223
    ml->discover( "." );
224
225
    bool discovered = cbMock->wait();
    ASSERT_TRUE( discovered );
226
227
228
229
230
231
232
233

    ASSERT_EQ( 3u, ml->files().size() );
    // Do not watch for live changes
    ml.reset();
    auto newFolder = std::string(mock::FileSystemFactory::Root) + "newfolder/";
    fsMock->addFolder( mock::FileSystemFactory::Root, "newfolder/", time( nullptr ) );
    fsMock->addFile( newFolder, "newfile.avi" );

234
235
    // This will trigger a reload
    cbMock->prepareForReload();
236
    Reload();
237
238
    bool reloaded = cbMock->waitForReload();
    ASSERT_TRUE( reloaded );
239
240
241
242
243

    ASSERT_EQ( 4u, ml->files().size() );
    auto file = ml->file( newFolder + "newfile.avi" );
    ASSERT_NE( nullptr, file );
}
244

245
// This is expected to fail until we fix the file system modifications detection
246
247
TEST_F( Folders, NewFileInSubFolder )
{
248
    cbMock->prepareForWait( 1 );
249
    ml->discover( "." );
250
251
252
    bool discovered = cbMock->wait();
    ASSERT_TRUE( discovered );

253
    auto f = ml->folder( mock::FileSystemFactory::Root );
254
    ASSERT_EQ( 3u, ml->files().size() );
255
256
257

    f = ml->folder( mock::FileSystemFactory::SubFolder );
    auto lmd = f->lastModificationDate();
258
259
260
261
    // Do not watch for live changes
    ml.reset();
    fsMock->addFile( mock::FileSystemFactory::SubFolder, "newfile.avi" );

262
    cbMock->prepareForReload();
263
    Reload();
264
265
    bool reloaded = cbMock->waitForReload();
    ASSERT_TRUE( reloaded );
266
267
268

    ASSERT_EQ( 4u, ml->files().size() );
    auto file = ml->file( std::string( mock::FileSystemFactory::SubFolder ) + "newfile.avi" );
269
    f = ml->folder( mock::FileSystemFactory::SubFolder );
270
271
    ASSERT_EQ( 2u, f->files().size() );
    ASSERT_NE( nullptr, file );
272
    ASSERT_FALSE( std::static_pointer_cast<Media>( file )->isStandAlone() );
273
    ASSERT_NE( lmd, f->lastModificationDate() );
274
}
275
276
277

TEST_F( Folders, RemoveFileFromDirectory )
{
278
    cbMock->prepareForWait( 1 );
279
    ml->discover( "." );
280
281
    bool discovered = cbMock->wait();
    ASSERT_TRUE( discovered );
282
283
284
285
286
287

    ASSERT_EQ( 3u, ml->files().size() );
    // Do not watch for live changes
    ml.reset();
    fsMock->removeFile( mock::FileSystemFactory::SubFolder, "subfile.mp4" );

288
    cbMock->prepareForReload();
289
    Reload();
290
291
    bool reloaded = cbMock->waitForReload();
    ASSERT_TRUE( reloaded );
292
293
294
295
296
297
298

    ASSERT_EQ( 2u, ml->files().size() );
    auto file = ml->file( std::string( mock::FileSystemFactory::SubFolder ) + "subfile.mp4" );
    auto f = ml->folder( mock::FileSystemFactory::SubFolder );
    ASSERT_EQ( 0u, f->files().size() );
    ASSERT_EQ( nullptr, file );
}
299
300
301

TEST_F( Folders, RemoveDirectory )
{
302
    cbMock->prepareForWait( 1 );
303
    ml->discover( "." );
304
305
    bool discovered = cbMock->wait();
    ASSERT_TRUE( discovered );
306
307
308
309
310
311

    ASSERT_EQ( 3u, ml->files().size() );
    // Do not watch for live changes
    ml.reset();
    fsMock->removeFolder( mock::FileSystemFactory::SubFolder );

312
    cbMock->prepareForReload();
313
    Reload();
314
315
    bool reloaded = cbMock->waitForReload();
    ASSERT_TRUE( reloaded );
316
317
318
319
320
321
322

    ASSERT_EQ( 2u, ml->files().size() );
    auto file = ml->file( std::string( mock::FileSystemFactory::SubFolder ) + "subfile.mp4" );
    auto f = ml->folder( mock::FileSystemFactory::SubFolder );
    ASSERT_EQ( nullptr, f );
    ASSERT_EQ( nullptr, file );
}
323
324
325

TEST_F( Folders, UpdateFile )
{
326
    cbMock->prepareForWait( 1 );
327
    ml->discover( "." );
328
329
330
    bool discovered = cbMock->wait();
    ASSERT_TRUE( discovered );

331
332
    auto filePath = std::string{ mock::FileSystemFactory::SubFolder } + "subfile.mp4";
    auto f = ml->file( filePath );
333
    ASSERT_NE( f, nullptr );
334
335
336
337
338
339
    auto id = f->id();

    ml.reset();
    fsMock->files[filePath]->markAsModified();
    fsMock->dirs[mock::FileSystemFactory::SubFolder]->markAsModified();

340
    cbMock->prepareForReload();
341
    Reload();
342
343
344
    bool reloaded = cbMock->waitForReload();
    ASSERT_TRUE( reloaded );

345
346
347
348
349
350
    f = ml->file( filePath );
    ASSERT_NE( nullptr, f );
    // The file is expected to be deleted and re-added since it changed, so the
    // id should have changed
    ASSERT_NE( id, f->id() );
}
351
352
353
354
355

// This simply tests that the flag is properly stored in db
TEST_F( Folders, CheckRemovable )
{
    fsMock->dirs[mock::FileSystemFactory::SubFolder]->markRemovable();
356
    cbMock->prepareForWait( 1 );
357
    ml->discover( "." );
358
359
360
    bool discovered = cbMock->wait();
    ASSERT_TRUE( discovered );

361
    auto f = ml->folder( mock::FileSystemFactory::Root );
362
    ASSERT_NE( f, nullptr );
363
364
    ASSERT_FALSE( f->isRemovable() );
    auto subfolder = ml->folder( mock::FileSystemFactory::SubFolder );
365
    ASSERT_NE( subfolder, nullptr );
366
367
    ASSERT_TRUE( subfolder->isRemovable() );

368
    // No actual FS change, no need to wait for the actual FS reload
369
370
371
372
373
374
375
    Reload();

    f = ml->folder( mock::FileSystemFactory::Root );
    ASSERT_FALSE( f->isRemovable() );
    subfolder = ml->folder( mock::FileSystemFactory::SubFolder );
    ASSERT_TRUE( subfolder->isRemovable() );
}