mirror of
https://github.com/immich-app/immich.git
synced 2025-12-26 09:14:58 +03:00
fix(server): ensure new exclusion patterns work (#12102)
* add test for bug * find excluded paths when checking offline * fix filename * fix unit tests * bump picomatch * fix e2e paths * improve e2e * add unit tests * cleanup e2e * set correct asset count * fix e2e test * fix lint
This commit is contained in:
committed by
GitHub
parent
c6c7c54fa5
commit
bab5ad7ebd
3
server/package-lock.json
generated
3
server/package-lock.json
generated
@@ -51,7 +51,7 @@
|
||||
"nodemailer": "^6.9.13",
|
||||
"openid-client": "^5.4.3",
|
||||
"pg": "^8.11.3",
|
||||
"picomatch": "^4.0.0",
|
||||
"picomatch": "^4.0.2",
|
||||
"react": "^18.3.1",
|
||||
"react-email": "^3.0.0",
|
||||
"reflect-metadata": "^0.2.0",
|
||||
@@ -11403,6 +11403,7 @@
|
||||
"version": "4.0.2",
|
||||
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz",
|
||||
"integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
},
|
||||
|
||||
@@ -77,7 +77,7 @@
|
||||
"nodemailer": "^6.9.13",
|
||||
"openid-client": "^5.4.3",
|
||||
"pg": "^8.11.3",
|
||||
"picomatch": "^4.0.0",
|
||||
"picomatch": "^4.0.2",
|
||||
"react": "^18.3.1",
|
||||
"react-email": "^3.0.0",
|
||||
"reflect-metadata": "^0.2.0",
|
||||
|
||||
@@ -133,6 +133,7 @@ export interface ILibraryFileJob extends IEntityJob {
|
||||
|
||||
export interface ILibraryOfflineJob extends IEntityJob {
|
||||
importPaths: string[];
|
||||
exclusionPatterns: string[];
|
||||
}
|
||||
|
||||
export interface ILibraryRefreshJob extends IEntityJob {
|
||||
|
||||
@@ -301,6 +301,7 @@ describe(LibraryService.name, () => {
|
||||
const mockAssetJob: ILibraryOfflineJob = {
|
||||
id: assetStub.external.id,
|
||||
importPaths: ['/'],
|
||||
exclusionPatterns: [],
|
||||
};
|
||||
|
||||
assetMock.getById.mockResolvedValue(null);
|
||||
@@ -314,6 +315,7 @@ describe(LibraryService.name, () => {
|
||||
const mockAssetJob: ILibraryOfflineJob = {
|
||||
id: assetStub.external.id,
|
||||
importPaths: ['/'],
|
||||
exclusionPatterns: [],
|
||||
};
|
||||
|
||||
assetMock.getById.mockResolvedValue(assetStub.offline);
|
||||
@@ -323,10 +325,25 @@ describe(LibraryService.name, () => {
|
||||
expect(assetMock.update).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should offline assets no longer on disk or matching exclusion pattern', async () => {
|
||||
it('should offline assets no longer on disk', async () => {
|
||||
const mockAssetJob: ILibraryOfflineJob = {
|
||||
id: assetStub.external.id,
|
||||
importPaths: ['/'],
|
||||
exclusionPatterns: [],
|
||||
};
|
||||
|
||||
assetMock.getById.mockResolvedValue(assetStub.external);
|
||||
|
||||
await expect(sut.handleOfflineCheck(mockAssetJob)).resolves.toBe(JobStatus.SUCCESS);
|
||||
|
||||
expect(assetMock.update).toHaveBeenCalledWith({ id: assetStub.external.id, isOffline: true });
|
||||
});
|
||||
|
||||
it('should offline assets matching an exclusion pattern', async () => {
|
||||
const mockAssetJob: ILibraryOfflineJob = {
|
||||
id: assetStub.external.id,
|
||||
importPaths: ['/'],
|
||||
exclusionPatterns: ['**/user1/**'],
|
||||
};
|
||||
|
||||
assetMock.getById.mockResolvedValue(assetStub.external);
|
||||
@@ -340,6 +357,7 @@ describe(LibraryService.name, () => {
|
||||
const mockAssetJob: ILibraryOfflineJob = {
|
||||
id: assetStub.external.id,
|
||||
importPaths: ['/data/user2'],
|
||||
exclusionPatterns: [],
|
||||
};
|
||||
|
||||
assetMock.getById.mockResolvedValue(assetStub.external);
|
||||
@@ -354,6 +372,7 @@ describe(LibraryService.name, () => {
|
||||
const mockAssetJob: ILibraryOfflineJob = {
|
||||
id: assetStub.external.id,
|
||||
importPaths: ['/'],
|
||||
exclusionPatterns: [],
|
||||
};
|
||||
|
||||
assetMock.getById.mockResolvedValue(assetStub.external);
|
||||
|
||||
@@ -556,11 +556,16 @@ export class LibraryService {
|
||||
return JobStatus.SUCCESS;
|
||||
}
|
||||
|
||||
const isExcluded = job.exclusionPatterns.some((pattern) => picomatch.isMatch(asset.originalPath, pattern));
|
||||
if (isExcluded) {
|
||||
this.logger.debug(`Asset is covered by an exclusion pattern, marking offline: ${asset.originalPath}`);
|
||||
await this.assetRepository.update({ id: asset.id, isOffline: true });
|
||||
return JobStatus.SUCCESS;
|
||||
}
|
||||
|
||||
const fileExists = await this.storageRepository.checkFileExists(asset.originalPath, R_OK);
|
||||
if (!fileExists) {
|
||||
this.logger.debug(
|
||||
`Asset is no longer found on disk or is covered by exclusion pattern, marking offline: ${asset.originalPath}`,
|
||||
);
|
||||
this.logger.debug(`Asset is no longer found on disk, marking offline: ${asset.originalPath}`);
|
||||
await this.assetRepository.update({ id: asset.id, isOffline: true });
|
||||
return JobStatus.SUCCESS;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user