Compare commits

...

1 Commits

Author SHA1 Message Date
shenlong-tanwen
93bd21e467 feat: add iCloudIdETag to AssetMetadataMobileAppDto 2025-11-13 22:06:05 +05:30
5 changed files with 58 additions and 11 deletions

View File

@@ -53,7 +53,7 @@ describe(AssetMediaController.name, () => {
});
it('should accept metadata', async () => {
const mobileMetadata = { key: AssetMetadataKey.MobileApp, value: { iCloudId: '123' } };
const mobileMetadata = { key: AssetMetadataKey.MobileApp, value: { iCloudId: '123', iCloudIdETag: 'etag123' } };
const { status } = await request(ctx.getHttpServer())
.post('/assets')
.attach('assetData', assetData, filename)
@@ -98,6 +98,19 @@ describe(AssetMediaController.name, () => {
expect(body).toEqual(factory.responses.badRequest(['metadata.0.value.iCloudId must be a string']));
});
it('should validate iCloudIdETag is a string', async () => {
const { status, body } = await request(ctx.getHttpServer())
.post('/assets')
.attach('assetData', assetData, filename)
.field({
...makeUploadDto(),
metadata: JSON.stringify([{ key: AssetMetadataKey.MobileApp, value: { iCloudIdETag: 123 } }]),
});
expect(status).toBe(400);
expect(body).toEqual(factory.responses.badRequest(['metadata.0.value.iCloudIdETag must be a string']));
});
it('should require `deviceAssetId`', async () => {
const { status, body } = await request(ctx.getHttpServer())
.post('/assets')

View File

@@ -190,6 +190,28 @@ describe(AssetController.name, () => {
describe(AssetMetadataKey.MobileApp, () => {
it('should accept valid data and pass to service correctly', async () => {
const assetId = factory.uuid();
const { status } = await request(ctx.getHttpServer())
.put(`/assets/${assetId}/metadata`)
.send({ items: [{ key: 'mobile-app', value: { iCloudId: '123', iCloudIdETag: 'etag123' } }] });
expect(service.upsertMetadata).toHaveBeenCalledWith(undefined, assetId, {
items: [{ key: 'mobile-app', value: { iCloudId: '123', iCloudIdETag: 'etag123' } }],
});
expect(status).toBe(200);
});
it('should work without iCloudId', async () => {
const assetId = factory.uuid();
const { status } = await request(ctx.getHttpServer())
.put(`/assets/${assetId}/metadata`)
.send({ items: [{ key: 'mobile-app', value: { iCloudIdETag: 'etag123' } }] });
expect(service.upsertMetadata).toHaveBeenCalledWith(undefined, assetId, {
items: [{ key: 'mobile-app', value: { iCloudIdETag: 'etag123' } }],
});
expect(status).toBe(200);
});
it('should work without iCloudIdETag', async () => {
const assetId = factory.uuid();
const { status } = await request(ctx.getHttpServer())
.put(`/assets/${assetId}/metadata`)
@@ -200,7 +222,7 @@ describe(AssetController.name, () => {
expect(status).toBe(200);
});
it('should work without iCloudId', async () => {
it('should work with empty object', async () => {
const assetId = factory.uuid();
const { status } = await request(ctx.getHttpServer())
.put(`/assets/${assetId}/metadata`)

View File

@@ -177,6 +177,10 @@ export class AssetMetadataMobileAppDto {
@IsString()
@Optional()
iCloudId?: string;
@IsString()
@Optional()
iCloudIdETag?: string;
}
export class AssetMetadataResponseDto {

View File

@@ -551,5 +551,5 @@ export type AssetMetadataItem<T extends keyof AssetMetadata = AssetMetadataKey>
};
export interface AssetMetadata extends Record<AssetMetadataKey, Record<string, any>> {
[AssetMetadataKey.MobileApp]: { iCloudId: string };
[AssetMetadataKey.MobileApp]: { iCloudId: string; iCloudIdETag: string };
}

View File

@@ -23,7 +23,9 @@ describe(SyncEntityType.AssetMetadataV1, () => {
const assetRepo = ctx.get(AssetRepository);
const { asset } = await ctx.newAsset({ ownerId: user.id });
await assetRepo.upsertMetadata(asset.id, [{ key: AssetMetadataKey.MobileApp, value: { iCloudId: 'abc123' } }]);
await assetRepo.upsertMetadata(asset.id, [
{ key: AssetMetadataKey.MobileApp, value: { iCloudId: 'abc123', iCloudIdETag: 'etag123' } },
]);
const response = await ctx.syncStream(auth, [SyncRequestType.AssetMetadataV1]);
expect(response).toEqual([
@@ -32,7 +34,7 @@ describe(SyncEntityType.AssetMetadataV1, () => {
data: {
key: AssetMetadataKey.MobileApp,
assetId: asset.id,
value: { iCloudId: 'abc123' },
value: { iCloudId: 'abc123', iCloudIdETag: 'etag123' },
},
type: 'AssetMetadataV1',
},
@@ -48,7 +50,9 @@ describe(SyncEntityType.AssetMetadataV1, () => {
const assetRepo = ctx.get(AssetRepository);
const { asset } = await ctx.newAsset({ ownerId: user.id });
await assetRepo.upsertMetadata(asset.id, [{ key: AssetMetadataKey.MobileApp, value: { iCloudId: 'abc123' } }]);
await assetRepo.upsertMetadata(asset.id, [
{ key: AssetMetadataKey.MobileApp, value: { iCloudId: 'abc123', iCloudIdETag: 'etag123' } },
]);
const response = await ctx.syncStream(auth, [SyncRequestType.AssetMetadataV1]);
expect(response).toEqual([
@@ -57,7 +61,7 @@ describe(SyncEntityType.AssetMetadataV1, () => {
data: {
key: AssetMetadataKey.MobileApp,
assetId: asset.id,
value: { iCloudId: 'abc123' },
value: { iCloudId: 'abc123', iCloudIdETag: 'etag123' },
},
type: 'AssetMetadataV1',
},
@@ -66,7 +70,9 @@ describe(SyncEntityType.AssetMetadataV1, () => {
await ctx.syncAckAll(auth, response);
await assetRepo.upsertMetadata(asset.id, [{ key: AssetMetadataKey.MobileApp, value: { iCloudId: 'abc456' } }]);
await assetRepo.upsertMetadata(asset.id, [
{ key: AssetMetadataKey.MobileApp, value: { iCloudId: 'abc456', iCloudIdETag: 'etag456' } },
]);
const updatedResponse = await ctx.syncStream(auth, [SyncRequestType.AssetMetadataV1]);
expect(updatedResponse).toEqual([
@@ -75,7 +81,7 @@ describe(SyncEntityType.AssetMetadataV1, () => {
data: {
key: AssetMetadataKey.MobileApp,
assetId: asset.id,
value: { iCloudId: 'abc456' },
value: { iCloudId: 'abc456', iCloudIdETag: 'etag456' },
},
type: 'AssetMetadataV1',
},
@@ -93,7 +99,9 @@ describe(SyncEntityType.AssetMetadataDeleteV1, () => {
const assetRepo = ctx.get(AssetRepository);
const { asset } = await ctx.newAsset({ ownerId: user.id });
await assetRepo.upsertMetadata(asset.id, [{ key: AssetMetadataKey.MobileApp, value: { iCloudId: 'abc123' } }]);
await assetRepo.upsertMetadata(asset.id, [
{ key: AssetMetadataKey.MobileApp, value: { iCloudId: 'abc123', iCloudIdETag: 'etag123' } },
]);
const response = await ctx.syncStream(auth, [SyncRequestType.AssetMetadataV1]);
expect(response).toEqual([
@@ -102,7 +110,7 @@ describe(SyncEntityType.AssetMetadataDeleteV1, () => {
data: {
key: AssetMetadataKey.MobileApp,
assetId: asset.id,
value: { iCloudId: 'abc123' },
value: { iCloudId: 'abc123', iCloudIdETag: 'etag123' },
},
type: 'AssetMetadataV1',
},