@ -706,7 +706,7 @@ describe(LibraryService.name, () => {
libraryMock . getUploadLibraryCount . mockResolvedValue ( 2 ) ;
libraryMock . get . mockResolvedValue ( libraryStub . externalLibrary1 ) ;
await sut . delete ( authStub. admin , libraryStub. externalLibrary1 . id ) ;
await sut . delete ( libraryStub. externalLibrary1 . id ) ;
expect ( jobMock . queue ) . toHaveBeenCalledWith ( {
name : JobName.LIBRARY_DELETE ,
@ -721,9 +721,7 @@ describe(LibraryService.name, () => {
libraryMock . getUploadLibraryCount . mockResolvedValue ( 1 ) ;
libraryMock . get . mockResolvedValue ( libraryStub . uploadLibrary1 ) ;
await expect ( sut . delete ( authStub . admin , libraryStub . uploadLibrary1 . id ) ) . rejects . toBeInstanceOf (
BadRequestException ,
) ;
await expect ( sut . delete ( libraryStub . uploadLibrary1 . id ) ) . rejects . toBeInstanceOf ( BadRequestException ) ;
expect ( jobMock . queue ) . not . toHaveBeenCalled ( ) ;
expect ( jobMock . queueAll ) . not . toHaveBeenCalled ( ) ;
@ -735,7 +733,7 @@ describe(LibraryService.name, () => {
libraryMock . getUploadLibraryCount . mockResolvedValue ( 1 ) ;
libraryMock . get . mockResolvedValue ( libraryStub . externalLibrary1 ) ;
await sut . delete ( authStub. admin , libraryStub. externalLibrary1 . id ) ;
await sut . delete ( libraryStub. externalLibrary1 . id ) ;
expect ( jobMock . queue ) . toHaveBeenCalledWith ( {
name : JobName.LIBRARY_DELETE ,
@ -757,26 +755,16 @@ describe(LibraryService.name, () => {
storageMock . watch . mockImplementation ( makeMockWatcher ( { close : mockClose } ) ) ;
await sut . init ( ) ;
await sut . delete ( authStub. admin , libraryStub. externalLibraryWithImportPaths1 . id ) ;
await sut . delete ( libraryStub. externalLibraryWithImportPaths1 . id ) ;
expect ( mockClose ) . toHaveBeenCalled ( ) ;
} ) ;
} ) ;
describe ( 'getCount' , ( ) = > {
it ( 'should call the repository' , async ( ) = > {
libraryMock . getCountForUser . mockResolvedValue ( 17 ) ;
await expect ( sut . getCount ( authStub . admin ) ) . resolves . toBe ( 17 ) ;
expect ( libraryMock . getCountForUser ) . toHaveBeenCalledWith ( authStub . admin . user . id ) ;
} ) ;
} ) ;
describe ( 'get' , ( ) = > {
it ( 'should return a library' , async ( ) = > {
libraryMock . get . mockResolvedValue ( libraryStub . uploadLibrary1 ) ;
await expect ( sut . get ( authStub. admin , libraryStub. uploadLibrary1 . id ) ) . resolves . toEqual (
await expect ( sut . get ( libraryStub . uploadLibrary1 . id ) ) . resolves . toEqual (
expect . objectContaining ( {
id : libraryStub.uploadLibrary1.id ,
name : libraryStub.uploadLibrary1.name ,
@ -789,15 +777,16 @@ describe(LibraryService.name, () => {
it ( 'should throw an error when a library is not found' , async ( ) = > {
libraryMock . get . mockResolvedValue ( null ) ;
await expect ( sut . get ( authStub. admin , libraryStub. uploadLibrary1 . id ) ) . rejects . toBeInstanceOf ( BadRequestException ) ;
await expect ( sut . get ( libraryStub. uploadLibrary1 . id ) ) . rejects . toBeInstanceOf ( BadRequestException ) ;
expect ( libraryMock . get ) . toHaveBeenCalledWith ( libraryStub . uploadLibrary1 . id ) ;
} ) ;
} ) ;
describe ( 'getStatistics' , ( ) = > {
it ( 'should return library statistics' , async ( ) = > {
libraryMock . get . mockResolvedValue ( libraryStub . uploadLibrary1 ) ;
libraryMock . getStatistics . mockResolvedValue ( { photos : 10 , videos : 0 , total : 10 , usage : 1337 } ) ;
await expect ( sut . getStatistics ( authStub. admin , libraryStub. uploadLibrary1 . id ) ) . resolves . toEqual ( {
await expect ( sut . getStatistics ( libraryStub. uploadLibrary1 . id ) ) . resolves . toEqual ( {
photos : 10 ,
videos : 0 ,
total : 10 ,
@ -812,11 +801,7 @@ describe(LibraryService.name, () => {
describe ( 'external library' , ( ) = > {
it ( 'should create with default settings' , async ( ) = > {
libraryMock . create . mockResolvedValue ( libraryStub . externalLibrary1 ) ;
await expect (
sut . create ( authStub . admin , {
type : LibraryType . EXTERNAL ,
} ) ,
) . resolves . toEqual (
await expect ( sut . create ( { ownerId : authStub.admin.user.id , type : LibraryType . EXTERNAL } ) ) . resolves . toEqual (
expect . objectContaining ( {
id : libraryStub.externalLibrary1.id ,
type : LibraryType . EXTERNAL ,
@ -845,10 +830,7 @@ describe(LibraryService.name, () => {
it ( 'should create with name' , async ( ) = > {
libraryMock . create . mockResolvedValue ( libraryStub . externalLibrary1 ) ;
await expect (
sut . create ( authStub . admin , {
type : LibraryType . EXTERNAL ,
name : 'My Awesome Library' ,
} ) ,
sut . create ( { ownerId : authStub.admin.user.id , type : LibraryType . EXTERNAL , name : 'My Awesome Library' } ) ,
) . resolves . toEqual (
expect . objectContaining ( {
id : libraryStub.externalLibrary1.id ,
@ -878,10 +860,7 @@ describe(LibraryService.name, () => {
it ( 'should create invisible' , async ( ) = > {
libraryMock . create . mockResolvedValue ( libraryStub . externalLibrary1 ) ;
await expect (
sut . create ( authStub . admin , {
type : LibraryType . EXTERNAL ,
isVisible : false ,
} ) ,
sut . create ( { ownerId : authStub.admin.user.id , type : LibraryType . EXTERNAL , isVisible : false } ) ,
) . resolves . toEqual (
expect . objectContaining ( {
id : libraryStub.externalLibrary1.id ,
@ -911,7 +890,8 @@ describe(LibraryService.name, () => {
it ( 'should create with import paths' , async ( ) = > {
libraryMock . create . mockResolvedValue ( libraryStub . externalLibrary1 ) ;
await expect (
sut . create ( authStub . admin , {
sut . create ( {
ownerId : authStub.admin.user.id ,
type : LibraryType . EXTERNAL ,
importPaths : [ '/data/images' , '/data/videos' ] ,
} ) ,
@ -948,7 +928,8 @@ describe(LibraryService.name, () => {
libraryMock . getAll . mockResolvedValue ( [ ] ) ;
await sut . init ( ) ;
await sut . create ( authStub . admin , {
await sut . create ( {
ownerId : authStub.admin.user.id ,
type : LibraryType . EXTERNAL ,
importPaths : libraryStub.externalLibraryWithImportPaths1.importPaths ,
} ) ;
@ -963,7 +944,8 @@ describe(LibraryService.name, () => {
it ( 'should create with exclusion patterns' , async ( ) = > {
libraryMock . create . mockResolvedValue ( libraryStub . externalLibrary1 ) ;
await expect (
sut . create ( authStub . admin , {
sut . create ( {
ownerId : authStub.admin.user.id ,
type : LibraryType . EXTERNAL ,
exclusionPatterns : [ '*.tmp' , '*.bak' ] ,
} ) ,
@ -997,11 +979,7 @@ describe(LibraryService.name, () => {
describe ( 'upload library' , ( ) = > {
it ( 'should create with default settings' , async ( ) = > {
libraryMock . create . mockResolvedValue ( libraryStub . uploadLibrary1 ) ;
await expect (
sut . create ( authStub . admin , {
type : LibraryType . UPLOAD ,
} ) ,
) . resolves . toEqual (
await expect ( sut . create ( { ownerId : authStub.admin.user.id , type : LibraryType . UPLOAD } ) ) . resolves . toEqual (
expect . objectContaining ( {
id : libraryStub.uploadLibrary1.id ,
type : LibraryType . UPLOAD ,
@ -1030,10 +1008,7 @@ describe(LibraryService.name, () => {
it ( 'should create with name' , async ( ) = > {
libraryMock . create . mockResolvedValue ( libraryStub . uploadLibrary1 ) ;
await expect (
sut . create ( authStub . admin , {
type : LibraryType . UPLOAD ,
name : 'My Awesome Library' ,
} ) ,
sut . create ( { ownerId : authStub.admin.user.id , type : LibraryType . UPLOAD , name : 'My Awesome Library' } ) ,
) . resolves . toEqual (
expect . objectContaining ( {
id : libraryStub.uploadLibrary1.id ,
@ -1062,7 +1037,8 @@ describe(LibraryService.name, () => {
it ( 'should not create with import paths' , async ( ) = > {
await expect (
sut . create ( authStub . admin , {
sut . create ( {
ownerId : authStub.admin.user.id ,
type : LibraryType . UPLOAD ,
importPaths : [ '/data/images' , '/data/videos' ] ,
} ) ,
@ -1073,7 +1049,8 @@ describe(LibraryService.name, () => {
it ( 'should not create with exclusion patterns' , async ( ) = > {
await expect (
sut . create ( authStub . admin , {
sut . create ( {
ownerId : authStub.admin.user.id ,
type : LibraryType . UPLOAD ,
exclusionPatterns : [ '*.tmp' , '*.bak' ] ,
} ) ,
@ -1084,10 +1061,7 @@ describe(LibraryService.name, () => {
it ( 'should not create watched' , async ( ) = > {
await expect (
sut . create ( authStub . admin , {
type : LibraryType . UPLOAD ,
isWatched : true ,
} ) ,
sut . create ( { ownerId : authStub.admin.user.id , type : LibraryType . UPLOAD , isWatched : true } ) ,
) . rejects . toBeInstanceOf ( BadRequestException ) ;
expect ( storageMock . watch ) . not . toHaveBeenCalled ( ) ;
@ -1117,14 +1091,9 @@ describe(LibraryService.name, () => {
it ( 'should update library' , async ( ) = > {
libraryMock . update . mockResolvedValue ( libraryStub . uploadLibrary1 ) ;
await expect ( sut . update ( authStub . admin , authStub . admin . user . id , { } ) ) . resolves . toEqual (
mapLibrary ( libraryStub . uploadLibrary1 ) ,
) ;
expect ( libraryMock . update ) . toHaveBeenCalledWith (
expect . objectContaining ( {
id : authStub.admin.user.id ,
} ) ,
) ;
libraryMock . get . mockResolvedValue ( libraryStub . uploadLibrary1 ) ;
await expect ( sut . update ( 'library-id' , { } ) ) . resolves . toEqual ( mapLibrary ( libraryStub . uploadLibrary1 ) ) ;
expect ( libraryMock . update ) . toHaveBeenCalledWith ( expect . objectContaining ( { id : 'library-id' } ) ) ;
} ) ;
it ( 'should re-watch library when updating import paths' , async ( ) = > {
@ -1137,15 +1106,11 @@ describe(LibraryService.name, () => {
storageMock . checkFileExists . mockResolvedValue ( true ) ;
await expect (
sut . update ( authStub . admin , authStub . admin . user . id , { importPaths : [ '/data/user1/foo' ] } ) ,
) . resolves . toEqual ( mapLibrary ( libraryStub . externalLibraryWithImportPaths1 ) ) ;
expect ( libraryMock . update ) . toHaveBeenCalledWith (
expect . objectContaining ( {
id : authStub.admin.user.id ,
} ) ,
await expect ( sut . update ( 'library-id' , { importPaths : [ '/data/user1/foo' ] } ) ) . resolves . toEqual (
mapLibrary ( libraryStub . externalLibraryWithImportPaths1 ) ,
) ;
expect ( libraryMock . update ) . toHaveBeenCalledWith ( expect . objectContaining ( { id : 'library-id' } ) ) ;
expect ( storageMock . watch ) . toHaveBeenCalledWith (
libraryStub . externalLibraryWithImportPaths1 . importPaths ,
expect . anything ( ) ,
@ -1158,15 +1123,11 @@ describe(LibraryService.name, () => {
configMock . load . mockResolvedValue ( systemConfigStub . libraryWatchEnabled ) ;
libraryMock . get . mockResolvedValue ( libraryStub . externalLibraryWithImportPaths1 ) ;
await expect ( sut . update ( authStub . admin , authStub . admin . user . id , { exclusionPatterns : [ 'bar' ] } ) ) . resolves . toEqual (
await expect ( sut . update ( 'library-id' , { exclusionPatterns : [ 'bar' ] } ) ) . resolves . toEqual (
mapLibrary ( libraryStub . externalLibraryWithImportPaths1 ) ,
) ;
expect ( libraryMock . update ) . toHaveBeenCalledWith (
expect . objectContaining ( {
id : authStub.admin.user.id ,
} ) ,
) ;
expect ( libraryMock . update ) . toHaveBeenCalledWith ( expect . objectContaining ( { id : 'library-id' } ) ) ;
expect ( storageMock . watch ) . toHaveBeenCalledWith (
expect . arrayContaining ( [ expect . any ( String ) ] ) ,
expect . anything ( ) ,
@ -1411,7 +1372,7 @@ describe(LibraryService.name, () => {
it ( 'should queue a library scan of external library' , async ( ) = > {
libraryMock . get . mockResolvedValue ( libraryStub . externalLibrary1 ) ;
await sut . queueScan ( authStub. admin , libraryStub. externalLibrary1 . id , { } ) ;
await sut . queueScan ( libraryStub. externalLibrary1 . id , { } ) ;
expect ( jobMock . queue . mock . calls ) . toEqual ( [
[
@ -1430,9 +1391,7 @@ describe(LibraryService.name, () => {
it ( 'should not queue a library scan of upload library' , async ( ) = > {
libraryMock . get . mockResolvedValue ( libraryStub . uploadLibrary1 ) ;
await expect ( sut . queueScan ( authStub . admin , libraryStub . uploadLibrary1 . id , { } ) ) . rejects . toBeInstanceOf (
BadRequestException ,
) ;
await expect ( sut . queueScan ( libraryStub . uploadLibrary1 . id , { } ) ) . rejects . toBeInstanceOf ( BadRequestException ) ;
expect ( jobMock . queue ) . not . toBeCalled ( ) ;
} ) ;
@ -1440,7 +1399,7 @@ describe(LibraryService.name, () => {
it ( 'should queue a library scan of all modified assets' , async ( ) = > {
libraryMock . get . mockResolvedValue ( libraryStub . externalLibrary1 ) ;
await sut . queueScan ( authStub. admin , libraryStub. externalLibrary1 . id , { refreshModifiedFiles : true } ) ;
await sut . queueScan ( libraryStub. externalLibrary1 . id , { refreshModifiedFiles : true } ) ;
expect ( jobMock . queue . mock . calls ) . toEqual ( [
[
@ -1459,7 +1418,7 @@ describe(LibraryService.name, () => {
it ( 'should queue a forced library scan' , async ( ) = > {
libraryMock . get . mockResolvedValue ( libraryStub . externalLibrary1 ) ;
await sut . queueScan ( authStub. admin , libraryStub. externalLibrary1 . id , { refreshAllFiles : true } ) ;
await sut . queueScan ( libraryStub. externalLibrary1 . id , { refreshAllFiles : true } ) ;
expect ( jobMock . queue . mock . calls ) . toEqual ( [
[
@ -1478,7 +1437,7 @@ describe(LibraryService.name, () => {
describe ( 'queueEmptyTrash' , ( ) = > {
it ( 'should queue the trash job' , async ( ) = > {
await sut . queueRemoveOffline ( authStub. admin , libraryStub. externalLibrary1 . id ) ;
await sut . queueRemoveOffline ( libraryStub. externalLibrary1 . id ) ;
expect ( jobMock . queue . mock . calls ) . toEqual ( [
[
@ -1566,17 +1525,15 @@ describe(LibraryService.name, () => {
storageMock . checkFileExists . mockResolvedValue ( true ) ;
const result = await sut . validate ( authStub . external1 , libraryStub . externalLibraryWithImportPaths1 . id , {
importPaths : [ '/data/user1/' ] ,
await expect ( sut . validate ( 'library-id' , { importPaths : [ '/data/user1/' ] } ) ) . resolves . toEqual ( {
importPaths : [
{
importPath : '/data/user1/' ,
isValid : true ,
message : undefined ,
} ,
] ,
} ) ;
expect ( result . importPaths ) . toEqual ( [
{
importPath : '/data/user1/' ,
isValid : true ,
message : undefined ,
} ,
] ) ;
} ) ;
it ( 'should detect when path does not exist' , async ( ) = > {
@ -1585,17 +1542,15 @@ describe(LibraryService.name, () => {
throw error ;
} ) ;
const result = await sut . validate ( authStub . external1 , libraryStub . externalLibraryWithImportPaths1 . id , {
importPaths : [ '/data/user1/' ] ,
await expect ( sut . validate ( 'library-id' , { importPaths : [ '/data/user1/' ] } ) ) . resolves . toEqual ( {
importPaths : [
{
importPath : '/data/user1/' ,
isValid : false ,
message : 'Path does not exist (ENOENT)' ,
} ,
] ,
} ) ;
expect ( result . importPaths ) . toEqual ( [
{
importPath : '/data/user1/' ,
isValid : false ,
message : 'Path does not exist (ENOENT)' ,
} ,
] ) ;
} ) ;
it ( 'should detect when path is not a directory' , async ( ) = > {
@ -1603,17 +1558,15 @@ describe(LibraryService.name, () => {
isDirectory : ( ) = > false ,
} as Stats ) ;
const result = await sut . validate ( authStub . external1 , libraryStub . externalLibraryWithImportPaths1 . id , {
importPaths : [ '/data/user1/file' ] ,
await expect ( sut . validate ( 'library-id' , { importPaths : [ '/data/user1/file' ] } ) ) . resolves . toEqual ( {
importPaths : [
{
importPath : '/data/user1/file' ,
isValid : false ,
message : 'Not a directory' ,
} ,
] ,
} ) ;
expect ( result . importPaths ) . toEqual ( [
{
importPath : '/data/user1/file' ,
isValid : false ,
message : 'Not a directory' ,
} ,
] ) ;
} ) ;
it ( 'should return an unknown exception from stat' , async ( ) = > {
@ -1621,17 +1574,15 @@ describe(LibraryService.name, () => {
throw new Error ( 'Unknown error' ) ;
} ) ;
const result = await sut . validate ( authStub . external1 , libraryStub . externalLibraryWithImportPaths1 . id , {
importPaths : [ '/data/user1/' ] ,
await expect ( sut . validate ( 'library-id' , { importPaths : [ '/data/user1/' ] } ) ) . resolves . toEqual ( {
importPaths : [
{
importPath : '/data/user1/' ,
isValid : false ,
message : 'Error: Unknown error' ,
} ,
] ,
} ) ;
expect ( result . importPaths ) . toEqual ( [
{
importPath : '/data/user1/' ,
isValid : false ,
message : 'Error: Unknown error' ,
} ,
] ) ;
} ) ;
it ( 'should detect when access rights are missing' , async ( ) = > {
@ -1641,17 +1592,15 @@ describe(LibraryService.name, () => {
storageMock . checkFileExists . mockResolvedValue ( false ) ;
const result = await sut . validate ( authStub . external1 , libraryStub . externalLibraryWithImportPaths1 . id , {
importPaths : [ '/data/user1/' ] ,
await expect ( sut . validate ( 'library-id' , { importPaths : [ '/data/user1/' ] } ) ) . resolves . toEqual ( {
importPaths : [
{
importPath : '/data/user1/' ,
isValid : false ,
message : 'Lacking read permission for folder' ,
} ,
] ,
} ) ;
expect ( result . importPaths ) . toEqual ( [
{
importPath : '/data/user1/' ,
isValid : false ,
message : 'Lacking read permission for folder' ,
} ,
] ) ;
} ) ;
it ( 'should detect when import path is in immich media folder' , async ( ) = > {
@ -1659,26 +1608,26 @@ describe(LibraryService.name, () => {
const validImport = libraryStub . hasImmichPaths . importPaths [ 1 ] ;
when ( storageMock . checkFileExists ) . calledWith ( validImport , R_OK ) . mockResolvedValue ( true ) ;
const result = await sut . validate ( authStub . external1 , libraryStub . hasImmichPaths . id , {
importPaths : libraryStub.hasImmichPaths.importPaths ,
await expect (
sut . validate ( 'library-id' , { importPaths : libraryStub.hasImmichPaths.importPaths } ) ,
) . resolves . toEqual ( {
importPaths : [
{
importPath : libraryStub.hasImmichPaths.importPaths [ 0 ] ,
isValid : false ,
message : 'Cannot use media upload folder for external libraries' ,
} ,
{
importPath : validImport ,
isValid : true ,
} ,
{
importPath : libraryStub.hasImmichPaths.importPaths [ 2 ] ,
isValid : false ,
message : 'Cannot use media upload folder for external libraries' ,
} ,
] ,
} ) ;
expect ( result . importPaths ) . toEqual ( [
{
importPath : libraryStub.hasImmichPaths.importPaths [ 0 ] ,
isValid : false ,
message : 'Cannot use media upload folder for external libraries' ,
} ,
{
importPath : validImport ,
isValid : true ,
} ,
{
importPath : libraryStub.hasImmichPaths.importPaths [ 2 ] ,
isValid : false ,
message : 'Cannot use media upload folder for external libraries' ,
} ,
] ) ;
} ) ;
} ) ;
} ) ;