@ -4,19 +4,20 @@ import {
IPersonRepository ,
LibraryResponseDto ,
LoginResponseDto ,
SharedLinkResponseDto ,
TimeBucketSize ,
WithoutProperty ,
mapAsset ,
usePagination ,
} from '@app/domain' ;
import { AssetController } from '@app/immich' ;
import { AssetEntity , AssetType , SharedLinkType } from '@app/infra/entities' ;
import { AssetEntity , AssetType , LibraryType, SharedLinkType } from '@app/infra/entities' ;
import { AssetRepository } from '@app/infra/repositories' ;
import { INestApplication } from '@nestjs/common' ;
import { api } from '@test/api' ;
import { errorStub , uuidStub } from '@test/fixtures' ;
import { db , testApp } from '@test/test-utils' ;
import { randomBytes } from 'crypto' ;
import { DateTime } from 'luxon' ;
import request from 'supertest' ;
const user1Dto = {
@ -31,6 +32,9 @@ const user2Dto = {
name : 'User 2' ,
} ;
const today = DateTime . fromObject ( { year : 2023 , month : 11 , day : 3 } ) ;
const yesterday = today . minus ( { days : 1 } ) ;
const makeUploadDto = ( options ? : { omit : string } ) : Record < string , any > = > {
const dto : Record < string , any > = {
deviceAssetId : 'example-image' ,
@ -49,83 +53,498 @@ const makeUploadDto = (options?: { omit: string }): Record<string, any> => {
return dto ;
} ;
let assetCount = 0 ;
const createAsset = (
repository : IAssetRepository ,
loginResponse : LoginResponseDto ,
libraryId : string ,
createdAt : Date ,
) : Promise < AssetEntity > = > {
const id = assetCount ++ ;
return repository . create ( {
ownerId : loginResponse.userId ,
checksum : randomBytes ( 20 ) ,
originalPath : ` /tests/test_ ${ id } ` ,
deviceAssetId : ` test_ ${ id } ` ,
deviceId : 'e2e-test' ,
libraryId ,
isVisible : true ,
fileCreatedAt : createdAt ,
fileModifiedAt : new Date ( ) ,
localDateTime : createdAt ,
type : AssetType . IMAGE ,
originalFileName : ` test_ ${ id } ` ,
} ) ;
} ;
describe ( ` ${ AssetController . name } (e2e) ` , ( ) = > {
let app : INestApplication ;
let server : any ;
let assetRepository : IAssetRepository ;
let defaultLibrary : LibraryResponseDto ;
let sharedLink : SharedLinkResponseDto ;
let user1 : LoginResponseDto ;
let user2 : LoginResponseDto ;
let asset1 : AssetEntity ;
let asset2 : AssetEntity ;
let asset3 : AssetEntity ;
let asset4 : AssetEntity ;
let libraries : LibraryResponseDto [ ] ;
let asset1 : AssetResponseDto ;
let asset2 : AssetResponseDto ;
let asset3 : AssetResponseDto ;
let asset4 : AssetResponseDto ;
let asset5 : AssetResponseDto ;
let assetCount = 0 ;
const createAsset = async ( loginResponse : LoginResponseDto , createdAt : Date , other : Partial < AssetEntity > = { } ) = > {
const id = assetCount ++ ;
const asset = await assetRepository . create ( {
createdAt : today.toJSDate ( ) ,
updatedAt : today.toJSDate ( ) ,
ownerId : loginResponse.userId ,
checksum : randomBytes ( 20 ) ,
originalPath : ` /tests/test_ ${ id } ` ,
deviceAssetId : ` test_ ${ id } ` ,
deviceId : 'e2e-test' ,
libraryId : (
libraries . find (
( { ownerId , type } ) = > ownerId === loginResponse . userId && type === LibraryType . UPLOAD ,
) as LibraryResponseDto
) . id ,
isVisible : true ,
fileCreatedAt : createdAt ,
fileModifiedAt : new Date ( ) ,
localDateTime : createdAt ,
type : AssetType . IMAGE ,
originalFileName : ` test_ ${ id } ` ,
. . . other ,
} ) ;
return mapAsset ( asset ) ;
} ;
beforeAll ( async ( ) = > {
[ server , app ] = await testApp . create ( ) ;
assetRepository = app . get < IAssetRepository > ( IAssetRepository ) ;
} ) ;
afterAll ( async ( ) = > {
await testApp . teardown ( ) ;
} ) ;
beforeEach ( async ( ) = > {
await db . reset ( ) ;
await api . authApi . adminSignUp ( server ) ;
const admin = await api . authApi . adminLogin ( server ) ;
const [ libraries ] = await Promise . all ( [
api . libraryApi . getAll ( server , admin . accessToken ) ,
await Promise . all ( [
api . userApi . create ( server , admin . accessToken , user1Dto ) ,
api . userApi . create ( server , admin . accessToken , user2Dto ) ,
] ) ;
defaultLibrary = libraries [ 0 ] ;
[ user1 , user2 ] = await Promise . all ( [
api . authApi . login ( server , { email : user1Dto.email , password : user1Dto.password } ) ,
api . authApi . login ( server , { email : user2Dto.email , password : user2Dto.password } ) ,
] ) ;
[ asset1 , asset2 , asset3 , asset4 ] = await Promise . all ( [
createAsset ( assetRepository , user1 , defaultLibrary . id , new Date ( '1970-01-01' ) ) ,
createAsset ( assetRepository , user1 , defaultLibrary . id , new Date ( '1970-01-02' ) ) ,
createAsset ( assetRepository , user1 , defaultLibrary . id , new Date ( '1970-02-01' ) ) ,
createAsset ( assetRepository , user2 , defaultLibrary . id , new Date ( '1970-01-01' ) ) ,
const [ user1Libraries , user2Libraries ] = await Promise . all ( [
api . libraryApi . getAll ( server , user1 . accessToken ) ,
api . libraryApi . getAll ( server , user2 . accessToken ) ,
] ) ;
sharedLink = await api . sharedLinkApi . create ( server , user1 . accessToken , {
type : SharedLinkType . INDIVIDUAL ,
assetIds : [ asset1 . id , asset2 . id ] ,
libraries = [ . . . user1Libraries , . . . user2Libraries ] ;
} ) ;
beforeEach ( async ( ) = > {
await db . reset ( { entities : [ AssetEntity ] } ) ;
[ asset1 , asset2 , asset3 , asset4 , asset5 ] = await Promise . all ( [
createAsset ( user1 , new Date ( '1970-01-01' ) ) ,
createAsset ( user1 , new Date ( '1970-02-10' ) ) ,
createAsset ( user1 , new Date ( '1970-02-11' ) , {
isFavorite : true ,
isArchived : true ,
isExternal : true ,
isReadOnly : true ,
type : AssetType . VIDEO ,
fileCreatedAt : yesterday.toJSDate ( ) ,
fileModifiedAt : yesterday.toJSDate ( ) ,
createdAt : yesterday.toJSDate ( ) ,
updatedAt : yesterday.toJSDate ( ) ,
localDateTime : yesterday.toJSDate ( ) ,
encodedVideoPath : '/path/to/encoded-video.mp4' ,
webpPath : '/path/to/thumb.webp' ,
resizePath : '/path/to/thumb.jpg' ,
} ) ,
createAsset ( user2 , new Date ( '1970-01-01' ) ) ,
createAsset ( user1 , new Date ( '1970-01-01' ) , {
deletedAt : yesterday.toJSDate ( ) ,
} ) ,
] ) ;
await assetRepository . upsertExif ( {
assetId : asset3.id ,
latitude : 90 ,
longitude : 90 ,
city : 'Immich' ,
state : 'Nebraska' ,
country : 'United States' ,
make : 'Cannon' ,
model : 'EOS Rebel T7' ,
lensModel : 'Fancy lens' ,
} ) ;
} ) ;
afterAll ( async ( ) = > {
await testApp . teardown ( ) ;
} ) ;
describe ( 'GET /assets' , ( ) = > {
it ( 'should require authentication' , async ( ) = > {
const { status , body } = await request ( server ) . get ( '/assets' ) ;
expect ( body ) . toEqual ( errorStub . unauthorized ) ;
expect ( status ) . toBe ( 401 ) ;
} ) ;
const badTests = [
//
{
should : 'should reject page as a string' ,
query : { page : 'abc' } ,
expected : [ 'page must not be less than 1' , 'page must be an integer number' ] ,
} ,
{
should : 'should reject page as a decimal' ,
query : { page : 1.5 } ,
expected : [ 'page must be an integer number' ] ,
} ,
{
should : 'should reject page as a negative number' ,
query : { page : - 10 } ,
expected : [ 'page must not be less than 1' ] ,
} ,
{
should : 'should reject page as 0' ,
query : { page : 0 } ,
expected : [ 'page must not be less than 1' ] ,
} ,
{
should : 'should reject size as a string' ,
query : { size : 'abc' } ,
expected : [ 'size must not be less than 1' , 'size must be an integer number' ] ,
} ,
{
should : 'should reject an invalid size' ,
query : { size : - 1.5 } ,
expected : [ 'size must not be less than 1' , 'size must be an integer number' ] ,
} ,
. . . [
'isArchived' ,
'isFavorite' ,
'isReadOnly' ,
'isExternal' ,
'isEncoded' ,
'isMotion' ,
'isOffline' ,
'isVisible' ,
] . map ( ( value ) = > ( {
should : ` should reject ${ value } not a boolean ` ,
query : { [ value ] : 'immich' } ,
expected : [ ` ${ value } must be a boolean value ` ] ,
} ) ) ,
] ;
for ( const { should , query , expected } of badTests ) {
it ( should , async ( ) = > {
const { status , body } = await request ( server )
. get ( '/assets' )
. set ( 'Authorization' , ` Bearer ${ user1 . accessToken } ` )
. query ( query ) ;
expect ( status ) . toBe ( 400 ) ;
expect ( body ) . toEqual ( errorStub . badRequest ( expected ) ) ;
} ) ;
}
const searchTests = [
{
should : 'should only return my own assets' ,
deferred : ( ) = > ( {
query : { } ,
assets : [ asset3 , asset2 , asset1 ] ,
} ) ,
} ,
{
should : 'should sort my assets in reverse' ,
deferred : ( ) = > ( {
query : { order : 'asc' } ,
assets : [ asset1 , asset2 , asset3 ] ,
} ) ,
} ,
{
should : 'should support custom page sizes' ,
deferred : ( ) = > ( {
query : { size : 1 } ,
assets : [ asset3 ] ,
} ) ,
} ,
{
should : 'should support pagination' ,
deferred : ( ) = > ( {
query : { size : 1 , page : 2 } ,
assets : [ asset2 ] ,
} ) ,
} ,
{
should : 'should search by checksum (base64)' ,
deferred : ( ) = > ( {
query : { checksum : asset1.checksum } ,
assets : [ asset1 ] ,
} ) ,
} ,
{
should : 'should search by checksum (hex)' ,
deferred : ( ) = > ( {
query : { checksum : Buffer.from ( asset1 . checksum , 'base64' ) . toString ( 'hex' ) } ,
assets : [ asset1 ] ,
} ) ,
} ,
{
should : 'should search by id' ,
deferred : ( ) = > ( {
query : { id : asset1.id } ,
assets : [ asset1 ] ,
} ) ,
} ,
{
should : 'should search by isFavorite (true)' ,
deferred : ( ) = > ( {
query : { isFavorite : true } ,
assets : [ asset3 ] ,
} ) ,
} ,
{
should : 'should search by isFavorite (false)' ,
deferred : ( ) = > ( {
query : { isFavorite : false } ,
assets : [ asset2 , asset1 ] ,
} ) ,
} ,
{
should : 'should search by isArchived (true)' ,
deferred : ( ) = > ( {
query : { isArchived : true } ,
assets : [ asset3 ] ,
} ) ,
} ,
{
should : 'should search by isArchived (false)' ,
deferred : ( ) = > ( {
query : { isArchived : false } ,
assets : [ asset2 , asset1 ] ,
} ) ,
} ,
{
should : 'should search by isReadOnly (true)' ,
deferred : ( ) = > ( {
query : { isReadOnly : true } ,
assets : [ asset3 ] ,
} ) ,
} ,
{
should : 'should search by isReadOnly (false)' ,
deferred : ( ) = > ( {
query : { isReadOnly : false } ,
assets : [ asset2 , asset1 ] ,
} ) ,
} ,
{
should : 'should search by type (image)' ,
deferred : ( ) = > ( {
query : { type : 'IMAGE' } ,
assets : [ asset2 , asset1 ] ,
} ) ,
} ,
{
should : 'should search by type (video)' ,
deferred : ( ) = > ( {
query : { type : 'VIDEO' } ,
assets : [ asset3 ] ,
} ) ,
} ,
{
should : 'should search by createdBefore' ,
deferred : ( ) = > ( {
query : { createdBefore : yesterday.plus ( { hour : 1 } ) . toJSDate ( ) } ,
assets : [ asset3 ] ,
} ) ,
} ,
{
should : 'should search by createdBefore (no results)' ,
deferred : ( ) = > ( {
query : { createdBefore : yesterday.minus ( { hour : 1 } ) . toJSDate ( ) } ,
assets : [ ] ,
} ) ,
} ,
{
should : 'should search by createdAfter' ,
deferred : ( ) = > ( {
query : { createdAfter : yesterday.minus ( { hour : 1 } ) . toJSDate ( ) } ,
assets : [ asset3 , asset2 , asset1 ] ,
} ) ,
} ,
{
should : 'should search by createdAfter (no results)' ,
deferred : ( ) = > ( {
query : { createdAfter : today.plus ( { hour : 1 } ) . toJSDate ( ) } ,
assets : [ ] ,
} ) ,
} ,
{
should : 'should search by updatedBefore' ,
deferred : ( ) = > ( {
query : { updatedBefore : yesterday.plus ( { hour : 1 } ) . toJSDate ( ) } ,
assets : [ asset3 ] ,
} ) ,
} ,
{
should : 'should search by updatedBefore (no results)' ,
deferred : ( ) = > ( {
query : { updatedBefore : yesterday.minus ( { hour : 1 } ) . toJSDate ( ) } ,
assets : [ ] ,
} ) ,
} ,
{
should : 'should search by updatedAfter' ,
deferred : ( ) = > ( {
query : { updatedAfter : yesterday.minus ( { hour : 1 } ) . toJSDate ( ) } ,
assets : [ asset3 , asset2 , asset1 ] ,
} ) ,
} ,
{
should : 'should search by updatedAfter (no results)' ,
deferred : ( ) = > ( {
query : { updatedAfter : today.plus ( { hour : 1 } ) . toJSDate ( ) } ,
assets : [ ] ,
} ) ,
} ,
{
should : 'should search by trashedBefore' ,
deferred : ( ) = > ( {
query : { trashedBefore : yesterday.plus ( { hour : 1 } ) . toJSDate ( ) } ,
assets : [ asset5 ] ,
} ) ,
} ,
{
should : 'should search by trashedBefore (no results)' ,
deferred : ( ) = > ( {
query : { trashedBefore : yesterday.minus ( { hour : 1 } ) . toJSDate ( ) } ,
assets : [ ] ,
} ) ,
} ,
{
should : 'should search by trashedAfter' ,
deferred : ( ) = > ( {
query : { trashedAfter : yesterday.minus ( { hour : 1 } ) . toJSDate ( ) } ,
assets : [ asset5 ] ,
} ) ,
} ,
{
should : 'should search by trashedAfter (no results)' ,
deferred : ( ) = > ( {
query : { trashedAfter : today.plus ( { hour : 1 } ) . toJSDate ( ) } ,
assets : [ ] ,
} ) ,
} ,
{
should : 'should search by takenBefore' ,
deferred : ( ) = > ( {
query : { takenBefore : yesterday.plus ( { hour : 1 } ) . toJSDate ( ) } ,
assets : [ asset3 , asset2 , asset1 ] ,
} ) ,
} ,
{
should : 'should search by takenBefore (no results)' ,
deferred : ( ) = > ( {
query : { takenBefore : yesterday.minus ( { years : 100 } ) . toJSDate ( ) } ,
assets : [ ] ,
} ) ,
} ,
{
should : 'should search by takenAfter' ,
deferred : ( ) = > ( {
query : { takenAfter : yesterday.minus ( { hour : 1 } ) . toJSDate ( ) } ,
assets : [ asset3 ] ,
} ) ,
} ,
{
should : 'should search by takenAfter (no results)' ,
deferred : ( ) = > ( {
query : { takenAfter : today.plus ( { hour : 1 } ) . toJSDate ( ) } ,
assets : [ ] ,
} ) ,
} ,
{
should : 'should search by originalPath' ,
deferred : ( ) = > ( {
query : { originalPath : asset1.originalPath } ,
assets : [ asset1 ] ,
} ) ,
} ,
{
should : 'should search by originalFilename' ,
deferred : ( ) = > ( {
query : { originalFileName : asset1.originalFileName } ,
assets : [ asset1 ] ,
} ) ,
} ,
{
should : 'should search by encodedVideoPath' ,
deferred : ( ) = > ( {
query : { encodedVideoPath : '/path/to/encoded-video.mp4' } ,
assets : [ asset3 ] ,
} ) ,
} ,
{
should : 'should search by resizePath' ,
deferred : ( ) = > ( {
query : { resizePath : '/path/to/thumb.jpg' } ,
assets : [ asset3 ] ,
} ) ,
} ,
{
should : 'should search by webpPath' ,
deferred : ( ) = > ( {
query : { webpPath : '/path/to/thumb.webp' } ,
assets : [ asset3 ] ,
} ) ,
} ,
{
should : 'should search by city' ,
deferred : ( ) = > ( {
query : { city : 'Immich' } ,
assets : [ asset3 ] ,
} ) ,
} ,
{
should : 'should search by state' ,
deferred : ( ) = > ( {
query : { state : 'Nebraska' } ,
assets : [ asset3 ] ,
} ) ,
} ,
{
should : 'should search by country' ,
deferred : ( ) = > ( {
query : { country : 'United States' } ,
assets : [ asset3 ] ,
} ) ,
} ,
{
should : 'sohuld search by make' ,
deferred : ( ) = > ( {
query : { make : 'Cannon' } ,
assets : [ asset3 ] ,
} ) ,
} ,
{
should : 'should search by country' ,
deferred : ( ) = > ( {
query : { model : 'EOS Rebel T7' } ,
assets : [ asset3 ] ,
} ) ,
} ,
{
should : 'should search by lensModel' ,
deferred : ( ) = > ( {
query : { lensModel : 'Fancy lens' } ,
assets : [ asset3 ] ,
} ) ,
} ,
] ;
for ( const { should , deferred } of searchTests ) {
it ( should , async ( ) = > {
const { assets , query } = deferred ( ) ;
const { status , body } = await request ( server )
. get ( '/assets' )
. query ( query )
. set ( 'Authorization' , ` Bearer ${ user1 . accessToken } ` ) ;
expect ( status ) . toBe ( 200 ) ;
expect ( body . length ) . toBe ( assets . length ) ;
for ( let i = 0 ; i < assets . length ; i ++ ) {
expect ( body [ i ] ) . toEqual ( expect . objectContaining ( { id : assets [ i ] . id } ) ) ;
}
} ) ;
}
} ) ;
describe ( 'POST /asset/upload' , ( ) = > {
it ( 'should require authentication' , async ( ) = > {
const { status , body } = await request ( server )
@ -369,8 +788,8 @@ describe(`${AssetController.name} (e2e)`, () => {
. get ( '/asset/statistics' )
. set ( 'Authorization' , ` Bearer ${ user1 . accessToken } ` ) ;
expect ( body ) . toEqual ( { images : 5 , videos : 1 , total : 6 } ) ;
expect ( status ) . toBe ( 200 ) ;
expect ( body ) . toEqual ( { images : 6 , videos : 0 , total : 6 } ) ;
} ) ;
it ( 'should return stats of all favored assets' , async ( ) = > {
@ -380,7 +799,7 @@ describe(`${AssetController.name} (e2e)`, () => {
. query ( { isFavorite : true } ) ;
expect ( status ) . toBe ( 200 ) ;
expect ( body ) . toEqual ( { images : 2 , videos : 0, total : 2 } ) ;
expect ( body ) . toEqual ( { images : 2 , videos : 1, total : 3 } ) ;
} ) ;
it ( 'should return stats of all archived assets' , async ( ) = > {
@ -390,7 +809,7 @@ describe(`${AssetController.name} (e2e)`, () => {
. query ( { isArchived : true } ) ;
expect ( status ) . toBe ( 200 ) ;
expect ( body ) . toEqual ( { images : 2 , videos : 0, total : 2 } ) ;
expect ( body ) . toEqual ( { images : 2 , videos : 1, total : 3 } ) ;
} ) ;
it ( 'should return stats of all favored and archived assets' , async ( ) = > {
@ -400,7 +819,7 @@ describe(`${AssetController.name} (e2e)`, () => {
. query ( { isFavorite : true , isArchived : true } ) ;
expect ( status ) . toBe ( 200 ) ;
expect ( body ) . toEqual ( { images : 1 , videos : 0, total : 1 } ) ;
expect ( body ) . toEqual ( { images : 1 , videos : 1, total : 2 } ) ;
} ) ;
it ( 'should return stats of all assets neither favored nor archived' , async ( ) = > {
@ -410,19 +829,19 @@ describe(`${AssetController.name} (e2e)`, () => {
. query ( { isFavorite : false , isArchived : false } ) ;
expect ( status ) . toBe ( 200 ) ;
expect ( body ) . toEqual ( { images : 3, videos : 0 , total : 3 } ) ;
expect ( body ) . toEqual ( { images : 2, videos : 0 , total : 2 } ) ;
} ) ;
} ) ;
describe ( 'GET /asset/random' , ( ) = > {
beforeAll ( async ( ) = > {
await Promise . all ( [
createAsset ( assetRepository, user1, defaultLibrary . id , new Date ( '1970-02-01' ) ) ,
createAsset ( assetRepository, user1, defaultLibrary . id , new Date ( '1970-02-01' ) ) ,
createAsset ( assetRepository, user1, defaultLibrary . id , new Date ( '1970-02-01' ) ) ,
createAsset ( assetRepository, user1, defaultLibrary . id , new Date ( '1970-02-01' ) ) ,
createAsset ( assetRepository, user1, defaultLibrary . id , new Date ( '1970-02-01' ) ) ,
createAsset ( assetRepository, user1, defaultLibrary . id , new Date ( '1970-02-01' ) ) ,
createAsset ( user1, new Date ( '1970-02-01' ) ) ,
createAsset ( user1, new Date ( '1970-02-01' ) ) ,
createAsset ( user1, new Date ( '1970-02-01' ) ) ,
createAsset ( user1, new Date ( '1970-02-01' ) ) ,
createAsset ( user1, new Date ( '1970-02-01' ) ) ,
createAsset ( user1, new Date ( '1970-02-01' ) ) ,
] ) ;
} ) ;
it ( 'should require authentication' , async ( ) = > {
@ -432,7 +851,7 @@ describe(`${AssetController.name} (e2e)`, () => {
expect ( body ) . toEqual ( errorStub . unauthorized ) ;
} ) ;
it ('should return 1 random assets' , async ( ) = > {
it .each ( Array ( 10 ) ) ('should return 1 random assets' , async ( ) = > {
const { status , body } = await request ( server )
. get ( '/asset/random' )
. set ( 'Authorization' , ` Bearer ${ user1 . accessToken } ` ) ;
@ -442,13 +861,14 @@ describe(`${AssetController.name} (e2e)`, () => {
const assets : AssetResponseDto [ ] = body ;
expect ( assets . length ) . toBe ( 1 ) ;
expect ( assets [ 0 ] . ownerId ) . toBe ( user1 . userId ) ;
// assets owned by user1
expect ( [ asset1 . id , asset2 . id , asset3 . id ] ) . toContain ( assets [ 0 ] . id ) ;
//
// assets owned by user2
expect ( assets [ 0 ] . id ) . not . toBe ( asset4 . id ) ;
// assets owned by user1
expect ( [ asset1 . id , asset2 . id , asset3 . id ] ) . toContain ( assets [ 0 ] . id ) ;
} ) ;
it ('should return 2 random assets' , async ( ) = > {
it .each ( Array ( 10 ) ) ('should return 2 random assets' , async ( ) = > {
const { status , body } = await request ( server )
. get ( '/asset/random?count=2' )
. set ( 'Authorization' , ` Bearer ${ user1 . accessToken } ` ) ;
@ -505,13 +925,19 @@ describe(`${AssetController.name} (e2e)`, () => {
expect ( status ) . toBe ( 200 ) ;
expect ( body ) . toEqual (
expect . arrayContaining ( [
{ count : 1 , timeBucket : asset3.fileCreatedAt.toISOString ( ) } ,
{ count : 2 , timeBucket : asset1.fileCreatedAt.toISOString ( ) } ,
{ count : 1 , timeBucket : '2023-11-01T00:00:00.000Z' } ,
{ count : 1 , timeBucket : '1970-01-01T00:00:00.000Z' } ,
{ count : 1 , timeBucket : '1970-02-01T00:00:00.000Z' } ,
] ) ,
) ;
} ) ;
it ( 'should not allow access for unrelated shared links' , async ( ) = > {
const sharedLink = await api . sharedLinkApi . create ( server , user1 . accessToken , {
type : SharedLinkType . INDIVIDUAL ,
assetIds : [ asset1 . id , asset2 . id ] ,
} ) ;
const { status , body } = await request ( server )
. get ( '/asset/time-buckets' )
. query ( { key : sharedLink.key , size : TimeBucketSize.MONTH } ) ;
@ -575,12 +1001,7 @@ describe(`${AssetController.name} (e2e)`, () => {
. query ( { size : TimeBucketSize.MONTH , timeBucket } ) ;
expect ( status ) . toBe ( 200 ) ;
expect ( body ) . toEqual (
expect . arrayContaining ( [
expect . objectContaining ( { id : asset1.id } ) ,
expect . objectContaining ( { id : asset2.id } ) ,
] ) ,
) ;
expect ( body ) . toEqual ( expect . arrayContaining ( [ expect . objectContaining ( { id : asset2.id } ) ] ) ) ;
} ) ;
it ( 'should return error if time bucket is requested with partners asset and archived' , async ( ) = > {
@ -649,16 +1070,12 @@ describe(`${AssetController.name} (e2e)`, () => {
it ( 'should get map markers for all non-archived assets' , async ( ) = > {
const { status , body } = await request ( server )
. get ( '/asset/map-marker' )
. query ( { isArchived : false } )
. set ( 'Authorization' , ` Bearer ${ user1 . accessToken } ` ) ;
expect ( status ) . toBe ( 200 ) ;
expect ( body ) . toHaveLength ( 2 ) ;
expect ( body ) . toEqual (
expect . arrayContaining ( [
expect . objectContaining ( { id : asset1.id } ) ,
expect . objectContaining ( { id : asset2.id } ) ,
] ) ,
) ;
expect ( body ) . toHaveLength ( 1 ) ;
expect ( body ) . toEqual ( expect . arrayContaining ( [ expect . objectContaining ( { id : asset2.id } ) ] ) ) ;
} ) ;
it ( 'should get all map markers' , async ( ) = > {
@ -711,8 +1128,10 @@ describe(`${AssetController.name} (e2e)`, () => {
} ) ;
it ( 'should add stack children' , async ( ) = > {
const parent = await createAsset ( assetRepository , user1 , defaultLibrary . id , new Date ( '1970-01-01' ) ) ;
const child = await createAsset ( assetRepository , user1 , defaultLibrary . id , new Date ( '1970-01-01' ) ) ;
const [ parent , child ] = await Promise . all ( [
createAsset ( user1 , new Date ( '1970-01-01' ) ) ,
createAsset ( user1 , new Date ( '1970-01-01' ) ) ,
] ) ;
const { status } = await request ( server )
. put ( '/asset' )
@ -752,7 +1171,7 @@ describe(`${AssetController.name} (e2e)`, () => {
} ) ;
it ( 'should merge stack children' , async ( ) = > {
const newParent = await createAsset ( assetRepository, user1, defaultLibrary . id , new Date ( '1970-01-01' ) ) ;
const newParent = await createAsset ( user1, new Date ( '1970-01-01' ) ) ;
const { status } = await request ( server )
. put ( '/asset' )
. set ( 'Authorization' , ` Bearer ${ user1 . accessToken } ` )