mirror of
https://github.com/immich-app/immich.git
synced 2026-02-04 08:49:01 +03:00
chore: wip tests
This commit is contained in:
@@ -6,6 +6,7 @@ import { Stats } from 'node:fs';
|
||||
import { Writable } from 'node:stream';
|
||||
import { AssetFace } from 'src/database';
|
||||
import { AuthDto, LoginResponseDto } from 'src/dtos/auth.dto';
|
||||
import { AssetEditActionListDto } from 'src/dtos/editing.dto';
|
||||
import {
|
||||
AlbumUserRole,
|
||||
AssetType,
|
||||
@@ -280,6 +281,11 @@ export class MediumTestContext<S extends BaseService = BaseService> {
|
||||
const result = await this.get(TagRepository).upsertAssetIds(tagsAssets);
|
||||
return { tagsAssets, result };
|
||||
}
|
||||
|
||||
async newEdits(assetId: string, dto: AssetEditActionListDto) {
|
||||
const edits = await this.get(AssetEditRepository).replaceAll(assetId, dto.edits);
|
||||
return { edits };
|
||||
}
|
||||
}
|
||||
|
||||
export class SyncTestContext extends MediumTestContext<SyncService> {
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
import { Kysely } from 'kysely';
|
||||
import { AssetEditAction, MirrorAxis } from 'src/dtos/editing.dto';
|
||||
import { AssetFaceCreateDto } from 'src/dtos/person.dto';
|
||||
import { AccessRepository } from 'src/repositories/access.repository';
|
||||
import { AssetEditRepository } from 'src/repositories/asset-edit.repository';
|
||||
import { AssetRepository } from 'src/repositories/asset.repository';
|
||||
import { DatabaseRepository } from 'src/repositories/database.repository';
|
||||
import { LoggingRepository } from 'src/repositories/logging.repository';
|
||||
import { PersonRepository } from 'src/repositories/person.repository';
|
||||
@@ -15,7 +19,7 @@ let defaultDatabase: Kysely<DB>;
|
||||
const setup = (db?: Kysely<DB>) => {
|
||||
return newMediumService(PersonService, {
|
||||
database: db || defaultDatabase,
|
||||
real: [AccessRepository, DatabaseRepository, PersonRepository],
|
||||
real: [AccessRepository, DatabaseRepository, PersonRepository, AssetRepository, AssetEditRepository],
|
||||
mock: [LoggingRepository, StorageRepository],
|
||||
});
|
||||
};
|
||||
@@ -77,4 +81,685 @@ describe(PersonService.name, () => {
|
||||
expect(storageMock.unlink).toHaveBeenCalledWith(person2.thumbnailPath);
|
||||
});
|
||||
});
|
||||
|
||||
describe('createFace', () => {
|
||||
it('should store and retrieve the face as-is when there are no edits', async () => {
|
||||
const { sut, ctx } = setup();
|
||||
const { user } = await ctx.newUser();
|
||||
const { person } = await ctx.newPerson({ ownerId: user.id });
|
||||
const { asset } = await ctx.newAsset({ id: factory.uuid(), ownerId: user.id, width: 200, height: 200 });
|
||||
await ctx.newExif({ assetId: asset.id, exifImageHeight: 200, exifImageWidth: 200 });
|
||||
|
||||
const auth = factory.auth({ user });
|
||||
|
||||
const dto: AssetFaceCreateDto = {
|
||||
imageWidth: 200,
|
||||
imageHeight: 200,
|
||||
x: 50,
|
||||
y: 50,
|
||||
width: 150,
|
||||
height: 150,
|
||||
personId: person.id,
|
||||
assetId: asset.id,
|
||||
};
|
||||
|
||||
await sut.createFace(auth, dto);
|
||||
|
||||
// retrieve an asset's faces
|
||||
const faces = sut.getFacesById(auth, { id: asset.id });
|
||||
|
||||
await expect(faces).resolves.toHaveLength(1);
|
||||
await expect(faces).resolves.toEqual(
|
||||
expect.arrayContaining([
|
||||
expect.objectContaining({
|
||||
person: expect.objectContaining({ id: person.id }),
|
||||
boundingBoxX1: 50,
|
||||
boundingBoxY1: 50,
|
||||
boundingBoxX2: 200,
|
||||
boundingBoxY2: 200,
|
||||
}),
|
||||
]),
|
||||
);
|
||||
});
|
||||
|
||||
it('should properly transform the coordinates when the asset is edited (Crop)', async () => {
|
||||
const { sut, ctx } = setup();
|
||||
const { user } = await ctx.newUser();
|
||||
const { person } = await ctx.newPerson({ ownerId: user.id });
|
||||
const { asset } = await ctx.newAsset({ id: factory.uuid(), ownerId: user.id, width: 150, height: 200 });
|
||||
await ctx.newExif({ assetId: asset.id, exifImageHeight: 200, exifImageWidth: 200 });
|
||||
|
||||
await ctx.newEdits(asset.id, {
|
||||
edits: [
|
||||
{
|
||||
action: AssetEditAction.Crop,
|
||||
parameters: {
|
||||
x: 50,
|
||||
y: 50,
|
||||
width: 150,
|
||||
height: 200,
|
||||
},
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
const auth = factory.auth({ user });
|
||||
|
||||
const dto: AssetFaceCreateDto = {
|
||||
imageWidth: 150,
|
||||
imageHeight: 200,
|
||||
x: 0,
|
||||
y: 0,
|
||||
width: 100,
|
||||
height: 100,
|
||||
personId: person.id,
|
||||
assetId: asset.id,
|
||||
};
|
||||
|
||||
await sut.createFace(auth, dto);
|
||||
|
||||
// retrieve an asset's faces
|
||||
const faces = sut.getFacesById(auth, { id: asset.id });
|
||||
|
||||
await expect(faces).resolves.toHaveLength(1);
|
||||
await expect(faces).resolves.toEqual(
|
||||
expect.arrayContaining([
|
||||
expect.objectContaining({
|
||||
person: expect.objectContaining({ id: person.id }),
|
||||
boundingBoxX1: 0,
|
||||
boundingBoxY1: 0,
|
||||
boundingBoxX2: 100,
|
||||
boundingBoxY2: 100,
|
||||
}),
|
||||
]),
|
||||
);
|
||||
|
||||
// remove edits and verify the stored coordinates map to the original image
|
||||
await ctx.get(AssetEditRepository).replaceAll(asset.id, []);
|
||||
|
||||
const facesAfterRemovingEdits = sut.getFacesById(auth, { id: asset.id });
|
||||
|
||||
await expect(facesAfterRemovingEdits).resolves.toHaveLength(1);
|
||||
await expect(facesAfterRemovingEdits).resolves.toEqual(
|
||||
expect.arrayContaining([
|
||||
expect.objectContaining({
|
||||
person: expect.objectContaining({ id: person.id }),
|
||||
boundingBoxX1: 50,
|
||||
boundingBoxY1: 50,
|
||||
boundingBoxX2: 150,
|
||||
boundingBoxY2: 150,
|
||||
}),
|
||||
]),
|
||||
);
|
||||
});
|
||||
|
||||
it.only('should properly transform the coordinates when the asset is edited (Rotate 90)', async () => {
|
||||
const { sut, ctx } = setup();
|
||||
const { user } = await ctx.newUser();
|
||||
const { person } = await ctx.newPerson({ ownerId: user.id });
|
||||
const { asset } = await ctx.newAsset({ id: factory.uuid(), ownerId: user.id, width: 200, height: 100 });
|
||||
await ctx.newExif({ assetId: asset.id, exifImageHeight: 100, exifImageWidth: 200 });
|
||||
|
||||
await ctx.newEdits(asset.id, {
|
||||
edits: [
|
||||
{
|
||||
action: AssetEditAction.Rotate,
|
||||
parameters: {
|
||||
angle: 90,
|
||||
},
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
const auth = factory.auth({ user });
|
||||
|
||||
const dto: AssetFaceCreateDto = {
|
||||
imageWidth: 200,
|
||||
imageHeight: 100,
|
||||
x: 25,
|
||||
y: 50,
|
||||
width: 50,
|
||||
height: 50,
|
||||
personId: person.id,
|
||||
assetId: asset.id,
|
||||
};
|
||||
|
||||
await sut.createFace(auth, dto);
|
||||
|
||||
const faces = sut.getFacesById(auth, { id: asset.id });
|
||||
await expect(faces).resolves.toHaveLength(1);
|
||||
await expect(faces).resolves.toEqual(
|
||||
expect.arrayContaining([
|
||||
expect.objectContaining({
|
||||
person: expect.objectContaining({ id: person.id }),
|
||||
boundingBoxX1: 25,
|
||||
boundingBoxY1: 50,
|
||||
boundingBoxX2: 75,
|
||||
boundingBoxY2: 100,
|
||||
}),
|
||||
]),
|
||||
);
|
||||
|
||||
// remove edits and verify the stored coordinates map to the original image
|
||||
await ctx.get(AssetEditRepository).replaceAll(asset.id, []);
|
||||
const facesAfterRemovingEdits = sut.getFacesById(auth, { id: asset.id });
|
||||
|
||||
await expect(facesAfterRemovingEdits).resolves.toEqual(
|
||||
expect.arrayContaining([
|
||||
expect.objectContaining({
|
||||
person: expect.objectContaining({ id: person.id }),
|
||||
boundingBoxX1: 50,
|
||||
boundingBoxY1: 25,
|
||||
boundingBoxX2: 150,
|
||||
boundingBoxY2: 75,
|
||||
}),
|
||||
]),
|
||||
);
|
||||
});
|
||||
|
||||
it('should properly transform the coordinates when the asset is edited (Mirror Horizontal)', async () => {
|
||||
const { sut, ctx } = setup();
|
||||
const { user } = await ctx.newUser();
|
||||
const { person } = await ctx.newPerson({ ownerId: user.id });
|
||||
const { asset } = await ctx.newAsset({ id: factory.uuid(), ownerId: user.id, width: 200, height: 100 });
|
||||
await ctx.newExif({ assetId: asset.id, exifImageHeight: 100, exifImageWidth: 200 });
|
||||
|
||||
await ctx.newEdits(asset.id, {
|
||||
edits: [
|
||||
{
|
||||
action: AssetEditAction.Mirror,
|
||||
parameters: {
|
||||
axis: MirrorAxis.Horizontal,
|
||||
},
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
const auth = factory.auth({ user });
|
||||
|
||||
const dto: AssetFaceCreateDto = {
|
||||
imageWidth: 200,
|
||||
imageHeight: 100,
|
||||
x: 50,
|
||||
y: 25,
|
||||
width: 100,
|
||||
height: 50,
|
||||
personId: person.id,
|
||||
assetId: asset.id,
|
||||
};
|
||||
|
||||
await sut.createFace(auth, dto);
|
||||
|
||||
const faces = sut.getFacesById(auth, { id: asset.id });
|
||||
await expect(faces).resolves.toHaveLength(1);
|
||||
await expect(faces).resolves.toEqual(
|
||||
expect.arrayContaining([
|
||||
expect.objectContaining({
|
||||
person: expect.objectContaining({ id: person.id }),
|
||||
boundingBoxX1: 50,
|
||||
boundingBoxY1: 25,
|
||||
boundingBoxX2: 150,
|
||||
boundingBoxY2: 75,
|
||||
}),
|
||||
]),
|
||||
);
|
||||
|
||||
// remove edits and verify the stored coordinates map to the original image
|
||||
await ctx.get(AssetEditRepository).replaceAll(asset.id, []);
|
||||
const facesAfterRemovingEdits = sut.getFacesById(auth, { id: asset.id });
|
||||
|
||||
await expect(facesAfterRemovingEdits).resolves.toEqual(
|
||||
expect.arrayContaining([
|
||||
expect.objectContaining({
|
||||
person: expect.objectContaining({ id: person.id }),
|
||||
boundingBoxX1: 50,
|
||||
boundingBoxY1: 25,
|
||||
boundingBoxX2: 150,
|
||||
boundingBoxY2: 75,
|
||||
}),
|
||||
]),
|
||||
);
|
||||
});
|
||||
|
||||
it('should properly transform the coordinates when the asset is edited (Crop + Rotate)', async () => {
|
||||
const { sut, ctx } = setup();
|
||||
const { user } = await ctx.newUser();
|
||||
const { person } = await ctx.newPerson({ ownerId: user.id });
|
||||
const { asset } = await ctx.newAsset({ id: factory.uuid(), ownerId: user.id, width: 150, height: 200 });
|
||||
await ctx.newExif({ assetId: asset.id, exifImageHeight: 200, exifImageWidth: 200 });
|
||||
|
||||
await ctx.newEdits(asset.id, {
|
||||
edits: [
|
||||
{
|
||||
action: AssetEditAction.Crop,
|
||||
parameters: {
|
||||
x: 50,
|
||||
y: 0,
|
||||
width: 150,
|
||||
height: 200,
|
||||
},
|
||||
},
|
||||
{
|
||||
action: AssetEditAction.Rotate,
|
||||
parameters: {
|
||||
angle: 90,
|
||||
},
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
const auth = factory.auth({ user });
|
||||
|
||||
const dto: AssetFaceCreateDto = {
|
||||
imageWidth: 200,
|
||||
imageHeight: 150,
|
||||
x: 50,
|
||||
y: 25,
|
||||
width: 100,
|
||||
height: 75,
|
||||
personId: person.id,
|
||||
assetId: asset.id,
|
||||
};
|
||||
|
||||
await sut.createFace(auth, dto);
|
||||
|
||||
const faces = sut.getFacesById(auth, { id: asset.id });
|
||||
await expect(faces).resolves.toHaveLength(1);
|
||||
await expect(faces).resolves.toEqual(
|
||||
expect.arrayContaining([
|
||||
expect.objectContaining({
|
||||
person: expect.objectContaining({ id: person.id }),
|
||||
boundingBoxX1: 50,
|
||||
boundingBoxY1: 25,
|
||||
boundingBoxX2: 150,
|
||||
boundingBoxY2: 100,
|
||||
}),
|
||||
]),
|
||||
);
|
||||
|
||||
// remove edits and verify the stored coordinates map to the original image
|
||||
await ctx.get(AssetEditRepository).replaceAll(asset.id, []);
|
||||
const facesAfterRemovingEdits = sut.getFacesById(auth, { id: asset.id });
|
||||
|
||||
await expect(facesAfterRemovingEdits).resolves.toEqual(
|
||||
expect.arrayContaining([
|
||||
expect.objectContaining({
|
||||
person: expect.objectContaining({ id: person.id }),
|
||||
boundingBoxX1: 75,
|
||||
boundingBoxY1: 50,
|
||||
boundingBoxX2: 150,
|
||||
boundingBoxY2: 150,
|
||||
}),
|
||||
]),
|
||||
);
|
||||
});
|
||||
|
||||
it('should properly transform the coordinates when the asset is edited (Crop + Mirror)', async () => {
|
||||
const { sut, ctx } = setup();
|
||||
const { user } = await ctx.newUser();
|
||||
const { person } = await ctx.newPerson({ ownerId: user.id });
|
||||
const { asset } = await ctx.newAsset({ id: factory.uuid(), ownerId: user.id, width: 150, height: 100 });
|
||||
await ctx.newExif({ assetId: asset.id, exifImageHeight: 100, exifImageWidth: 200 });
|
||||
|
||||
await ctx.newEdits(asset.id, {
|
||||
edits: [
|
||||
{
|
||||
action: AssetEditAction.Crop,
|
||||
parameters: {
|
||||
x: 50,
|
||||
y: 0,
|
||||
width: 150,
|
||||
height: 100,
|
||||
},
|
||||
},
|
||||
{
|
||||
action: AssetEditAction.Mirror,
|
||||
parameters: {
|
||||
axis: MirrorAxis.Horizontal,
|
||||
},
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
const auth = factory.auth({ user });
|
||||
|
||||
const dto: AssetFaceCreateDto = {
|
||||
imageWidth: 150,
|
||||
imageHeight: 100,
|
||||
x: 25,
|
||||
y: 25,
|
||||
width: 75,
|
||||
height: 50,
|
||||
personId: person.id,
|
||||
assetId: asset.id,
|
||||
};
|
||||
|
||||
await sut.createFace(auth, dto);
|
||||
|
||||
const faces = sut.getFacesById(auth, { id: asset.id });
|
||||
await expect(faces).resolves.toHaveLength(1);
|
||||
await expect(faces).resolves.toEqual(
|
||||
expect.arrayContaining([
|
||||
expect.objectContaining({
|
||||
person: expect.objectContaining({ id: person.id }),
|
||||
boundingBoxX1: 25,
|
||||
boundingBoxY1: 25,
|
||||
boundingBoxX2: 100,
|
||||
boundingBoxY2: 75,
|
||||
}),
|
||||
]),
|
||||
);
|
||||
|
||||
// remove edits and verify the stored coordinates map to the original image
|
||||
await ctx.get(AssetEditRepository).replaceAll(asset.id, []);
|
||||
const facesAfterRemovingEdits = sut.getFacesById(auth, { id: asset.id });
|
||||
|
||||
await expect(facesAfterRemovingEdits).resolves.toEqual(
|
||||
expect.arrayContaining([
|
||||
expect.objectContaining({
|
||||
person: expect.objectContaining({ id: person.id }),
|
||||
boundingBoxX1: 100,
|
||||
boundingBoxY1: 25,
|
||||
boundingBoxX2: 175,
|
||||
boundingBoxY2: 75,
|
||||
}),
|
||||
]),
|
||||
);
|
||||
});
|
||||
|
||||
it('should properly transform the coordinates when the asset is edited (Rotate + Mirror)', async () => {
|
||||
const { sut, ctx } = setup();
|
||||
const { user } = await ctx.newUser();
|
||||
const { person } = await ctx.newPerson({ ownerId: user.id });
|
||||
const { asset } = await ctx.newAsset({ id: factory.uuid(), ownerId: user.id, width: 150, height: 200 });
|
||||
await ctx.newExif({ assetId: asset.id, exifImageHeight: 200, exifImageWidth: 150 });
|
||||
|
||||
await ctx.newEdits(asset.id, {
|
||||
edits: [
|
||||
{
|
||||
action: AssetEditAction.Rotate,
|
||||
parameters: {
|
||||
angle: 90,
|
||||
},
|
||||
},
|
||||
{
|
||||
action: AssetEditAction.Mirror,
|
||||
parameters: {
|
||||
axis: MirrorAxis.Horizontal,
|
||||
},
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
const auth = factory.auth({ user });
|
||||
|
||||
const dto: AssetFaceCreateDto = {
|
||||
imageWidth: 200,
|
||||
imageHeight: 150,
|
||||
x: 50,
|
||||
y: 25,
|
||||
width: 100,
|
||||
height: 75,
|
||||
personId: person.id,
|
||||
assetId: asset.id,
|
||||
};
|
||||
|
||||
await sut.createFace(auth, dto);
|
||||
|
||||
const faces = sut.getFacesById(auth, { id: asset.id });
|
||||
await expect(faces).resolves.toHaveLength(1);
|
||||
await expect(faces).resolves.toEqual(
|
||||
expect.arrayContaining([
|
||||
expect.objectContaining({
|
||||
person: expect.objectContaining({ id: person.id }),
|
||||
boundingBoxX1: 50,
|
||||
boundingBoxY1: 25,
|
||||
boundingBoxX2: 150,
|
||||
boundingBoxY2: 100,
|
||||
}),
|
||||
]),
|
||||
);
|
||||
|
||||
// remove edits and verify the stored coordinates map to the original image
|
||||
await ctx.get(AssetEditRepository).replaceAll(asset.id, []);
|
||||
const facesAfterRemovingEdits = sut.getFacesById(auth, { id: asset.id });
|
||||
|
||||
await expect(facesAfterRemovingEdits).resolves.toEqual(
|
||||
expect.arrayContaining([
|
||||
expect.objectContaining({
|
||||
person: expect.objectContaining({ id: person.id }),
|
||||
boundingBoxX1: 75,
|
||||
boundingBoxY1: 50,
|
||||
boundingBoxX2: 150,
|
||||
boundingBoxY2: 150,
|
||||
}),
|
||||
]),
|
||||
);
|
||||
});
|
||||
|
||||
it('should properly transform the coordinates when the asset is edited (Crop + Rotate + Mirror)', async () => {
|
||||
const { sut, ctx } = setup();
|
||||
const { user } = await ctx.newUser();
|
||||
const { person } = await ctx.newPerson({ ownerId: user.id });
|
||||
const { asset } = await ctx.newAsset({ id: factory.uuid(), ownerId: user.id, width: 100, height: 150 });
|
||||
await ctx.newExif({ assetId: asset.id, exifImageHeight: 200, exifImageWidth: 200 });
|
||||
|
||||
await ctx.newEdits(asset.id, {
|
||||
edits: [
|
||||
{
|
||||
action: AssetEditAction.Crop,
|
||||
parameters: {
|
||||
x: 50,
|
||||
y: 25,
|
||||
width: 150,
|
||||
height: 150,
|
||||
},
|
||||
},
|
||||
{
|
||||
action: AssetEditAction.Rotate,
|
||||
parameters: {
|
||||
angle: 270,
|
||||
},
|
||||
},
|
||||
{
|
||||
action: AssetEditAction.Mirror,
|
||||
parameters: {
|
||||
axis: MirrorAxis.Horizontal,
|
||||
},
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
const auth = factory.auth({ user });
|
||||
|
||||
const dto: AssetFaceCreateDto = {
|
||||
imageWidth: 150,
|
||||
imageHeight: 150,
|
||||
x: 25,
|
||||
y: 50,
|
||||
width: 75,
|
||||
height: 50,
|
||||
personId: person.id,
|
||||
assetId: asset.id,
|
||||
};
|
||||
|
||||
await sut.createFace(auth, dto);
|
||||
|
||||
const faces = sut.getFacesById(auth, { id: asset.id });
|
||||
await expect(faces).resolves.toHaveLength(1);
|
||||
await expect(faces).resolves.toEqual(
|
||||
expect.arrayContaining([
|
||||
expect.objectContaining({
|
||||
person: expect.objectContaining({ id: person.id }),
|
||||
boundingBoxX1: 25,
|
||||
boundingBoxY1: 50,
|
||||
boundingBoxX2: 100,
|
||||
boundingBoxY2: 100,
|
||||
}),
|
||||
]),
|
||||
);
|
||||
|
||||
// remove edits and verify the stored coordinates map to the original image
|
||||
await ctx.get(AssetEditRepository).replaceAll(asset.id, []);
|
||||
const facesAfterRemovingEdits = sut.getFacesById(auth, { id: asset.id });
|
||||
|
||||
await expect(facesAfterRemovingEdits).resolves.toEqual(
|
||||
expect.arrayContaining([
|
||||
expect.objectContaining({
|
||||
person: expect.objectContaining({ id: person.id }),
|
||||
boundingBoxX1: 100,
|
||||
boundingBoxY1: 75,
|
||||
boundingBoxX2: 150,
|
||||
boundingBoxY2: 150,
|
||||
}),
|
||||
]),
|
||||
);
|
||||
});
|
||||
|
||||
it('should properly transform the coordinates with multiple crops in sequence', async () => {
|
||||
const { sut, ctx } = setup();
|
||||
const { user } = await ctx.newUser();
|
||||
const { person } = await ctx.newPerson({ ownerId: user.id });
|
||||
const { asset } = await ctx.newAsset({ id: factory.uuid(), ownerId: user.id, width: 100, height: 100 });
|
||||
await ctx.newExif({ assetId: asset.id, exifImageHeight: 200, exifImageWidth: 200 });
|
||||
|
||||
await ctx.newEdits(asset.id, {
|
||||
edits: [
|
||||
{
|
||||
action: AssetEditAction.Crop,
|
||||
parameters: {
|
||||
x: 50,
|
||||
y: 50,
|
||||
width: 150,
|
||||
height: 150,
|
||||
},
|
||||
},
|
||||
{
|
||||
action: AssetEditAction.Crop,
|
||||
parameters: {
|
||||
x: 25,
|
||||
y: 25,
|
||||
width: 100,
|
||||
height: 100,
|
||||
},
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
const auth = factory.auth({ user });
|
||||
|
||||
const dto: AssetFaceCreateDto = {
|
||||
imageWidth: 100,
|
||||
imageHeight: 100,
|
||||
x: 10,
|
||||
y: 10,
|
||||
width: 80,
|
||||
height: 80,
|
||||
personId: person.id,
|
||||
assetId: asset.id,
|
||||
};
|
||||
|
||||
await sut.createFace(auth, dto);
|
||||
|
||||
const faces = sut.getFacesById(auth, { id: asset.id });
|
||||
await expect(faces).resolves.toHaveLength(1);
|
||||
await expect(faces).resolves.toEqual(
|
||||
expect.arrayContaining([
|
||||
expect.objectContaining({
|
||||
person: expect.objectContaining({ id: person.id }),
|
||||
boundingBoxX1: 10,
|
||||
boundingBoxY1: 10,
|
||||
boundingBoxX2: 90,
|
||||
boundingBoxY2: 90,
|
||||
}),
|
||||
]),
|
||||
);
|
||||
|
||||
// remove edits and verify the stored coordinates map to the original image
|
||||
await ctx.get(AssetEditRepository).replaceAll(asset.id, []);
|
||||
const facesAfterRemovingEdits = sut.getFacesById(auth, { id: asset.id });
|
||||
|
||||
await expect(facesAfterRemovingEdits).resolves.toEqual(
|
||||
expect.arrayContaining([
|
||||
expect.objectContaining({
|
||||
person: expect.objectContaining({ id: person.id }),
|
||||
boundingBoxX1: 85,
|
||||
boundingBoxY1: 85,
|
||||
boundingBoxX2: 165,
|
||||
boundingBoxY2: 165,
|
||||
}),
|
||||
]),
|
||||
);
|
||||
});
|
||||
|
||||
it('should properly transform the coordinates with multiple mirrors in sequence', async () => {
|
||||
const { sut, ctx } = setup();
|
||||
const { user } = await ctx.newUser();
|
||||
const { person } = await ctx.newPerson({ ownerId: user.id });
|
||||
const { asset } = await ctx.newAsset({ id: factory.uuid(), ownerId: user.id, width: 100, height: 100 });
|
||||
await ctx.newExif({ assetId: asset.id, exifImageHeight: 100, exifImageWidth: 100 });
|
||||
|
||||
await ctx.newEdits(asset.id, {
|
||||
edits: [
|
||||
{
|
||||
action: AssetEditAction.Mirror,
|
||||
parameters: {
|
||||
axis: MirrorAxis.Horizontal,
|
||||
},
|
||||
},
|
||||
{
|
||||
action: AssetEditAction.Mirror,
|
||||
parameters: {
|
||||
axis: MirrorAxis.Vertical,
|
||||
},
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
const auth = factory.auth({ user });
|
||||
|
||||
const dto: AssetFaceCreateDto = {
|
||||
imageWidth: 100,
|
||||
imageHeight: 100,
|
||||
x: 10,
|
||||
y: 10,
|
||||
width: 80,
|
||||
height: 80,
|
||||
personId: person.id,
|
||||
assetId: asset.id,
|
||||
};
|
||||
|
||||
await sut.createFace(auth, dto);
|
||||
|
||||
const faces = sut.getFacesById(auth, { id: asset.id });
|
||||
await expect(faces).resolves.toHaveLength(1);
|
||||
await expect(faces).resolves.toEqual(
|
||||
expect.arrayContaining([
|
||||
expect.objectContaining({
|
||||
person: expect.objectContaining({ id: person.id }),
|
||||
boundingBoxX1: 10,
|
||||
boundingBoxY1: 10,
|
||||
boundingBoxX2: 90,
|
||||
boundingBoxY2: 90,
|
||||
}),
|
||||
]),
|
||||
);
|
||||
|
||||
// remove edits and verify the stored coordinates map to the original image
|
||||
await ctx.get(AssetEditRepository).replaceAll(asset.id, []);
|
||||
const facesAfterRemovingEdits = sut.getFacesById(auth, { id: asset.id });
|
||||
|
||||
await expect(facesAfterRemovingEdits).resolves.toEqual(
|
||||
expect.arrayContaining([
|
||||
expect.objectContaining({
|
||||
person: expect.objectContaining({ id: person.id }),
|
||||
boundingBoxX1: 10,
|
||||
boundingBoxY1: 10,
|
||||
boundingBoxX2: 90,
|
||||
boundingBoxY2: 90,
|
||||
}),
|
||||
]),
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user