mirror of
https://github.com/immich-app/immich.git
synced 2026-04-24 18:10:01 -04:00
assume 3.0 client
This commit is contained in:
parent
9726f31235
commit
e9d23493cd
@ -445,7 +445,6 @@ export type SyncItem = {
|
||||
[SyncEntityType.UserDeleteV1]: SyncUserDeleteV1;
|
||||
[SyncEntityType.PartnerV1]: SyncPartnerV1;
|
||||
[SyncEntityType.PartnerDeleteV1]: SyncPartnerDeleteV1;
|
||||
[SyncEntityType.AssetV1]: SyncAssetV1;
|
||||
[SyncEntityType.AssetV2]: SyncAssetV2;
|
||||
[SyncEntityType.AssetDeleteV1]: SyncAssetDeleteV1;
|
||||
[SyncEntityType.AssetMetadataV1]: SyncAssetMetadataV1;
|
||||
@ -453,9 +452,7 @@ export type SyncItem = {
|
||||
[SyncEntityType.AssetExifV1]: SyncAssetExifV1;
|
||||
[SyncEntityType.AssetEditV1]: SyncAssetEditV1;
|
||||
[SyncEntityType.AssetEditDeleteV1]: SyncAssetEditDeleteV1;
|
||||
[SyncEntityType.PartnerAssetV1]: SyncAssetV1;
|
||||
[SyncEntityType.PartnerAssetV2]: SyncAssetV2;
|
||||
[SyncEntityType.PartnerAssetBackfillV1]: SyncAssetV1;
|
||||
[SyncEntityType.PartnerAssetBackfillV2]: SyncAssetV2;
|
||||
[SyncEntityType.PartnerAssetDeleteV1]: SyncAssetDeleteV1;
|
||||
[SyncEntityType.PartnerAssetExifV1]: SyncAssetExifV1;
|
||||
@ -466,11 +463,8 @@ export type SyncItem = {
|
||||
[SyncEntityType.AlbumUserV1]: SyncAlbumUserV1;
|
||||
[SyncEntityType.AlbumUserBackfillV1]: SyncAlbumUserV1;
|
||||
[SyncEntityType.AlbumUserDeleteV1]: SyncAlbumUserDeleteV1;
|
||||
[SyncEntityType.AlbumAssetCreateV1]: SyncAssetV1;
|
||||
[SyncEntityType.AlbumAssetCreateV2]: SyncAssetV2;
|
||||
[SyncEntityType.AlbumAssetUpdateV1]: SyncAssetV1;
|
||||
[SyncEntityType.AlbumAssetUpdateV2]: SyncAssetV2;
|
||||
[SyncEntityType.AlbumAssetBackfillV1]: SyncAssetV1;
|
||||
[SyncEntityType.AlbumAssetBackfillV2]: SyncAssetV2;
|
||||
[SyncEntityType.AlbumAssetExifCreateV1]: SyncAssetExifV1;
|
||||
[SyncEntityType.AlbumAssetExifUpdateV1]: SyncAssetExifV1;
|
||||
|
||||
@ -9,7 +9,6 @@ import {
|
||||
SyncAckSetDto,
|
||||
syncAlbumV2ToV1,
|
||||
syncAssetFaceV2ToV1,
|
||||
SyncAssetV1,
|
||||
SyncAssetV2,
|
||||
SyncItem,
|
||||
SyncStreamDto,
|
||||
@ -23,8 +22,7 @@ import { hexOrBufferToBase64 } from 'src/utils/bytes';
|
||||
import { fromAck, serialize, SerializeOptions, toAck } from 'src/utils/sync';
|
||||
|
||||
type CheckpointMap = Partial<Record<SyncEntityType, SyncAck>>;
|
||||
type AssetLike = Omit<SyncAssetV1, 'checksum' | 'thumbhash' | 'duration'> & {
|
||||
duration: number | null;
|
||||
type AssetLike = Omit<SyncAssetV2, 'checksum' | 'thumbhash'> & {
|
||||
checksum: Buffer<ArrayBufferLike>;
|
||||
thumbhash: Buffer<ArrayBufferLike> | null;
|
||||
};
|
||||
@ -33,13 +31,6 @@ const COMPLETE_ID = 'complete';
|
||||
const MAX_DAYS = 30;
|
||||
const MAX_DURATION = Duration.fromObject({ days: MAX_DAYS });
|
||||
|
||||
const mapSyncAssetV1 = ({ checksum, thumbhash, ...data }: AssetLike): SyncAssetV1 => ({
|
||||
...data,
|
||||
duration: Duration.fromMillis(data.duration ?? 0).toFormat('hh:mm:ss.SSS'),
|
||||
checksum: hexOrBufferToBase64(checksum),
|
||||
thumbhash: thumbhash ? hexOrBufferToBase64(thumbhash) : null,
|
||||
});
|
||||
|
||||
const mapSyncAssetV2 = ({ checksum, thumbhash, ...data }: AssetLike): SyncAssetV2 => ({
|
||||
...data,
|
||||
checksum: hexOrBufferToBase64(checksum),
|
||||
@ -167,15 +158,13 @@ export class SyncService extends BaseService {
|
||||
const { nowId } = await this.syncCheckpointRepository.getNow();
|
||||
const options: SyncQueryOptions = { nowId, userId: auth.user.id };
|
||||
|
||||
const handlers: Record<SyncRequestType, () => Promise<void>> = {
|
||||
const handlers = {
|
||||
[SyncRequestType.AuthUsersV1]: () => this.syncAuthUsersV1(options, response, checkpointMap),
|
||||
[SyncRequestType.UsersV1]: () => this.syncUsersV1(options, response, checkpointMap),
|
||||
[SyncRequestType.PartnersV1]: () => this.syncPartnersV1(options, response, checkpointMap),
|
||||
[SyncRequestType.AssetsV1]: () => this.syncAssetsV1(options, response, checkpointMap),
|
||||
[SyncRequestType.AssetsV2]: () => this.syncAssetsV2(options, response, checkpointMap),
|
||||
[SyncRequestType.AssetExifsV1]: () => this.syncAssetExifsV1(options, response, checkpointMap),
|
||||
[SyncRequestType.AssetEditsV1]: () => this.syncAssetEditsV1(options, response, checkpointMap),
|
||||
[SyncRequestType.PartnerAssetsV1]: () => this.syncPartnerAssetsV1(options, response, checkpointMap, session.id),
|
||||
[SyncRequestType.PartnerAssetsV2]: () => this.syncPartnerAssetsV2(options, response, checkpointMap, session.id),
|
||||
[SyncRequestType.AssetMetadataV1]: () => this.syncAssetMetadataV1(options, response, checkpointMap, auth),
|
||||
[SyncRequestType.PartnerAssetExifsV1]: () =>
|
||||
@ -183,7 +172,6 @@ export class SyncService extends BaseService {
|
||||
[SyncRequestType.AlbumsV1]: () => this.syncAlbumsV1(options, response, checkpointMap),
|
||||
[SyncRequestType.AlbumsV2]: () => this.syncAlbumsV2(options, response, checkpointMap),
|
||||
[SyncRequestType.AlbumUsersV1]: () => this.syncAlbumUsersV1(options, response, checkpointMap, session.id),
|
||||
[SyncRequestType.AlbumAssetsV1]: () => this.syncAlbumAssetsV1(options, response, checkpointMap, session.id),
|
||||
[SyncRequestType.AlbumAssetsV2]: () => this.syncAlbumAssetsV2(options, response, checkpointMap, session.id),
|
||||
[SyncRequestType.AlbumToAssetsV1]: () => this.syncAlbumToAssetsV1(options, response, checkpointMap, session.id),
|
||||
[SyncRequestType.AlbumAssetExifsV1]: () =>
|
||||
@ -196,10 +184,16 @@ export class SyncService extends BaseService {
|
||||
[SyncRequestType.AssetFacesV1]: async () => this.syncAssetFacesV1(options, response, checkpointMap),
|
||||
[SyncRequestType.AssetFacesV2]: async () => this.syncAssetFacesV2(options, response, checkpointMap),
|
||||
[SyncRequestType.UserMetadataV1]: () => this.syncUserMetadataV1(options, response, checkpointMap),
|
||||
};
|
||||
} as const;
|
||||
|
||||
for (const type of dto.types) {
|
||||
if (!(type in handlers)) {
|
||||
throw new BadRequestException(`Invalid sync type requested: ${type}`);
|
||||
}
|
||||
}
|
||||
|
||||
for (const type of SYNC_TYPES_ORDER.filter((type) => dto.types.includes(type))) {
|
||||
const handler = handlers[type];
|
||||
const handler = handlers[type as keyof typeof handlers];
|
||||
await handler();
|
||||
}
|
||||
|
||||
@ -275,20 +269,6 @@ export class SyncService extends BaseService {
|
||||
}
|
||||
}
|
||||
|
||||
private async syncAssetsV1(options: SyncQueryOptions, response: Writable, checkpointMap: CheckpointMap) {
|
||||
const deleteType = SyncEntityType.AssetDeleteV1;
|
||||
const deletes = this.syncRepository.asset.getDeletes({ ...options, ack: checkpointMap[deleteType] });
|
||||
for await (const { id, ...data } of deletes) {
|
||||
send(response, { type: deleteType, ids: [id], data });
|
||||
}
|
||||
|
||||
const upsertType = SyncEntityType.AssetV1;
|
||||
const upserts = this.syncRepository.asset.getUpserts({ ...options, ack: checkpointMap[upsertType] });
|
||||
for await (const { updateId, ...data } of upserts) {
|
||||
send(response, { type: upsertType, ids: [updateId], data: mapSyncAssetV1(data) });
|
||||
}
|
||||
}
|
||||
|
||||
private async syncAssetsV2(options: SyncQueryOptions, response: Writable, checkpointMap: CheckpointMap) {
|
||||
const deleteType = SyncEntityType.AssetDeleteV1;
|
||||
const deletes = this.syncRepository.asset.getDeletes({ ...options, ack: checkpointMap[deleteType] });
|
||||
@ -303,65 +283,6 @@ export class SyncService extends BaseService {
|
||||
}
|
||||
}
|
||||
|
||||
private async syncPartnerAssetsV1(
|
||||
options: SyncQueryOptions,
|
||||
response: Writable,
|
||||
checkpointMap: CheckpointMap,
|
||||
sessionId: string,
|
||||
) {
|
||||
const deleteType = SyncEntityType.PartnerAssetDeleteV1;
|
||||
const deletes = this.syncRepository.partnerAsset.getDeletes({ ...options, ack: checkpointMap[deleteType] });
|
||||
for await (const { id, ...data } of deletes) {
|
||||
send(response, { type: deleteType, ids: [id], data });
|
||||
}
|
||||
|
||||
const backfillType = SyncEntityType.PartnerAssetBackfillV1;
|
||||
const backfillCheckpoint = checkpointMap[backfillType];
|
||||
const partners = await this.syncRepository.partner.getCreatedAfter({
|
||||
...options,
|
||||
afterCreateId: backfillCheckpoint?.updateId,
|
||||
});
|
||||
const upsertType = SyncEntityType.PartnerAssetV1;
|
||||
const upsertCheckpoint = checkpointMap[upsertType];
|
||||
if (upsertCheckpoint) {
|
||||
const endId = upsertCheckpoint.updateId;
|
||||
|
||||
for (const partner of partners) {
|
||||
const createId = partner.createId;
|
||||
if (isEntityBackfillComplete(createId, backfillCheckpoint)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const startId = getStartId(createId, backfillCheckpoint);
|
||||
const backfill = this.syncRepository.partnerAsset.getBackfill(
|
||||
{ ...options, afterUpdateId: startId, beforeUpdateId: endId },
|
||||
partner.sharedById,
|
||||
);
|
||||
|
||||
for await (const { updateId, ...data } of backfill) {
|
||||
send(response, {
|
||||
type: backfillType,
|
||||
ids: [createId, updateId],
|
||||
data: mapSyncAssetV1(data),
|
||||
});
|
||||
}
|
||||
|
||||
sendEntityBackfillCompleteAck(response, backfillType, createId);
|
||||
}
|
||||
} else if (partners.length > 0) {
|
||||
await this.upsertBackfillCheckpoint({
|
||||
type: backfillType,
|
||||
sessionId,
|
||||
createId: partners.at(-1)!.createId,
|
||||
});
|
||||
}
|
||||
|
||||
const upserts = this.syncRepository.partnerAsset.getUpserts({ ...options, ack: checkpointMap[upsertType] });
|
||||
for await (const { updateId, ...data } of upserts) {
|
||||
send(response, { type: upsertType, ids: [updateId], data: mapSyncAssetV1(data) });
|
||||
}
|
||||
}
|
||||
|
||||
private async syncPartnerAssetsV2(
|
||||
options: SyncQueryOptions,
|
||||
response: Writable,
|
||||
@ -578,77 +499,6 @@ export class SyncService extends BaseService {
|
||||
}
|
||||
}
|
||||
|
||||
private async syncAlbumAssetsV1(
|
||||
options: SyncQueryOptions,
|
||||
response: Writable,
|
||||
checkpointMap: CheckpointMap,
|
||||
sessionId: string,
|
||||
) {
|
||||
const backfillType = SyncEntityType.AlbumAssetBackfillV1;
|
||||
const backfillCheckpoint = checkpointMap[backfillType];
|
||||
const albums = await this.syncRepository.album.getCreatedAfter({
|
||||
...options,
|
||||
afterCreateId: backfillCheckpoint?.updateId,
|
||||
});
|
||||
const updateType = SyncEntityType.AlbumAssetUpdateV1;
|
||||
const createType = SyncEntityType.AlbumAssetCreateV1;
|
||||
const updateCheckpoint = checkpointMap[updateType];
|
||||
const createCheckpoint = checkpointMap[createType];
|
||||
if (createCheckpoint) {
|
||||
const endId = createCheckpoint.updateId;
|
||||
|
||||
for (const album of albums) {
|
||||
const createId = album.createId;
|
||||
if (isEntityBackfillComplete(createId, backfillCheckpoint)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const startId = getStartId(createId, backfillCheckpoint);
|
||||
const backfill = this.syncRepository.albumAsset.getBackfill(
|
||||
{ ...options, afterUpdateId: startId, beforeUpdateId: endId },
|
||||
album.id,
|
||||
);
|
||||
|
||||
for await (const { updateId, ...data } of backfill) {
|
||||
send(response, { type: backfillType, ids: [createId, updateId], data: mapSyncAssetV1(data) });
|
||||
}
|
||||
|
||||
sendEntityBackfillCompleteAck(response, backfillType, createId);
|
||||
}
|
||||
} else if (albums.length > 0) {
|
||||
await this.upsertBackfillCheckpoint({
|
||||
type: backfillType,
|
||||
sessionId,
|
||||
createId: albums.at(-1)!.createId,
|
||||
});
|
||||
}
|
||||
|
||||
if (createCheckpoint) {
|
||||
const updates = this.syncRepository.albumAsset.getUpdates(
|
||||
{ ...options, ack: updateCheckpoint },
|
||||
createCheckpoint,
|
||||
);
|
||||
for await (const { updateId, ...data } of updates) {
|
||||
send(response, { type: updateType, ids: [updateId], data: mapSyncAssetV1(data) });
|
||||
}
|
||||
}
|
||||
|
||||
const creates = this.syncRepository.albumAsset.getCreates({ ...options, ack: createCheckpoint });
|
||||
let first = true;
|
||||
for await (const { updateId, ...data } of creates) {
|
||||
if (first) {
|
||||
send(response, {
|
||||
type: SyncEntityType.SyncAckV1,
|
||||
data: {},
|
||||
ackType: SyncEntityType.AlbumAssetUpdateV1,
|
||||
ids: [options.nowId],
|
||||
});
|
||||
first = false;
|
||||
}
|
||||
send(response, { type: createType, ids: [updateId], data: mapSyncAssetV1(data) });
|
||||
}
|
||||
}
|
||||
|
||||
private async syncAlbumAssetsV2(
|
||||
options: SyncQueryOptions,
|
||||
response: Writable,
|
||||
@ -711,7 +561,7 @@ export class SyncService extends BaseService {
|
||||
send(response, {
|
||||
type: SyncEntityType.SyncAckV1,
|
||||
data: {},
|
||||
ackType: SyncEntityType.AlbumAssetUpdateV1,
|
||||
ackType: SyncEntityType.AlbumAssetUpdateV2,
|
||||
ids: [options.nowId],
|
||||
});
|
||||
first = false;
|
||||
|
||||
@ -16,7 +16,7 @@ const createAsset = (
|
||||
type: AssetType.Image,
|
||||
thumbhash: null,
|
||||
localDateTime: new Date().toISOString(),
|
||||
duration: '0:00:00.00000',
|
||||
duration: 0,
|
||||
hasMetadata: true,
|
||||
width: 1920,
|
||||
height: 1080,
|
||||
|
||||
@ -15,13 +15,13 @@ const setup = async (db?: Kysely<DB>) => {
|
||||
};
|
||||
|
||||
const updateSyncAck = {
|
||||
ack: expect.stringContaining(SyncEntityType.AlbumAssetUpdateV1),
|
||||
ack: expect.stringContaining(SyncEntityType.AlbumAssetUpdateV2),
|
||||
data: {},
|
||||
type: SyncEntityType.SyncAckV1,
|
||||
};
|
||||
|
||||
const backfillSyncAck = {
|
||||
ack: expect.stringContaining(SyncEntityType.AlbumAssetBackfillV1),
|
||||
ack: expect.stringContaining(SyncEntityType.AlbumAssetBackfillV2),
|
||||
data: {},
|
||||
type: SyncEntityType.SyncAckV1,
|
||||
};
|
||||
@ -30,7 +30,7 @@ beforeAll(async () => {
|
||||
defaultDatabase = await getKyselyDB();
|
||||
});
|
||||
|
||||
describe(SyncRequestType.AlbumAssetsV1, () => {
|
||||
describe(SyncRequestType.AlbumAssetsV2, () => {
|
||||
it('should detect and sync the first album asset', async () => {
|
||||
const originalFileName = 'firstAsset';
|
||||
const checksum = '1115vHcVkZzNp3Q9G+FEA0nu6zUbGb4Tj4UOXkN0wRA=';
|
||||
@ -48,7 +48,7 @@ describe(SyncRequestType.AlbumAssetsV1, () => {
|
||||
fileModifiedAt: date,
|
||||
localDateTime: date,
|
||||
deletedAt: null,
|
||||
duration: '0:10:00.00000',
|
||||
duration: 600_000,
|
||||
livePhotoVideoId: null,
|
||||
stackId: null,
|
||||
libraryId: null,
|
||||
@ -59,7 +59,7 @@ describe(SyncRequestType.AlbumAssetsV1, () => {
|
||||
await ctx.newAlbumAsset({ albumId: album.id, assetId: asset.id });
|
||||
await ctx.newAlbumUser({ albumId: album.id, userId: auth.user.id, role: AlbumUserRole.Editor });
|
||||
|
||||
const response = await ctx.syncStream(auth, [SyncRequestType.AlbumAssetsV1]);
|
||||
const response = await ctx.syncStream(auth, [SyncRequestType.AlbumAssetsV2]);
|
||||
expect(response).toEqual([
|
||||
updateSyncAck,
|
||||
{
|
||||
@ -85,13 +85,13 @@ describe(SyncRequestType.AlbumAssetsV1, () => {
|
||||
height: asset.height,
|
||||
isEdited: asset.isEdited,
|
||||
},
|
||||
type: SyncEntityType.AlbumAssetCreateV1,
|
||||
type: SyncEntityType.AlbumAssetCreateV2,
|
||||
},
|
||||
expect.objectContaining({ type: SyncEntityType.SyncCompleteV1 }),
|
||||
]);
|
||||
|
||||
await ctx.syncAckAll(auth, response);
|
||||
await ctx.assertSyncIsComplete(auth, [SyncRequestType.AlbumAssetsV1]);
|
||||
await ctx.assertSyncIsComplete(auth, [SyncRequestType.AlbumAssetsV2]);
|
||||
});
|
||||
|
||||
it('should sync album asset for own user', async () => {
|
||||
@ -100,13 +100,13 @@ describe(SyncRequestType.AlbumAssetsV1, () => {
|
||||
const { album } = await ctx.newAlbum({ ownerId: auth.user.id });
|
||||
await ctx.newAlbumAsset({ albumId: album.id, assetId: asset.id });
|
||||
|
||||
await expect(ctx.syncStream(auth, [SyncRequestType.AssetsV1])).resolves.toEqual([
|
||||
expect.objectContaining({ type: SyncEntityType.AssetV1 }),
|
||||
await expect(ctx.syncStream(auth, [SyncRequestType.AssetsV2])).resolves.toEqual([
|
||||
expect.objectContaining({ type: SyncEntityType.AssetV2 }),
|
||||
expect.objectContaining({ type: SyncEntityType.SyncCompleteV1 }),
|
||||
]);
|
||||
await expect(ctx.syncStream(auth, [SyncRequestType.AlbumAssetsV1])).resolves.toEqual([
|
||||
await expect(ctx.syncStream(auth, [SyncRequestType.AlbumAssetsV2])).resolves.toEqual([
|
||||
expect.objectContaining({ type: SyncEntityType.SyncAckV1 }),
|
||||
expect.objectContaining({ type: SyncEntityType.AlbumAssetCreateV1 }),
|
||||
expect.objectContaining({ type: SyncEntityType.AlbumAssetCreateV2 }),
|
||||
expect.objectContaining({ type: SyncEntityType.SyncCompleteV1 }),
|
||||
]);
|
||||
});
|
||||
@ -122,11 +122,11 @@ describe(SyncRequestType.AlbumAssetsV1, () => {
|
||||
const { session } = await ctx.newSession({ userId: user3.id });
|
||||
const authUser3 = factory.auth({ session, user: user3 });
|
||||
|
||||
await expect(ctx.syncStream(authUser3, [SyncRequestType.AssetsV1])).resolves.toEqual([
|
||||
expect.objectContaining({ type: SyncEntityType.AssetV1 }),
|
||||
await expect(ctx.syncStream(authUser3, [SyncRequestType.AssetsV2])).resolves.toEqual([
|
||||
expect.objectContaining({ type: SyncEntityType.AssetV2 }),
|
||||
expect.objectContaining({ type: SyncEntityType.SyncCompleteV1 }),
|
||||
]);
|
||||
await ctx.assertSyncIsComplete(auth, [SyncRequestType.AlbumAssetsV1]);
|
||||
await ctx.assertSyncIsComplete(auth, [SyncRequestType.AlbumAssetsV2]);
|
||||
});
|
||||
|
||||
it('should backfill album assets when a user shares an album with you', async () => {
|
||||
@ -147,7 +147,7 @@ describe(SyncRequestType.AlbumAssetsV1, () => {
|
||||
await wait(2);
|
||||
await ctx.newAlbumUser({ albumId: album1.id, userId: auth.user.id, role: AlbumUserRole.Editor });
|
||||
|
||||
const response = await ctx.syncStream(auth, [SyncRequestType.AlbumAssetsV1]);
|
||||
const response = await ctx.syncStream(auth, [SyncRequestType.AlbumAssetsV2]);
|
||||
expect(response).toEqual([
|
||||
updateSyncAck,
|
||||
{
|
||||
@ -155,7 +155,7 @@ describe(SyncRequestType.AlbumAssetsV1, () => {
|
||||
data: expect.objectContaining({
|
||||
id: asset2User2.id,
|
||||
}),
|
||||
type: SyncEntityType.AlbumAssetCreateV1,
|
||||
type: SyncEntityType.AlbumAssetCreateV2,
|
||||
},
|
||||
expect.objectContaining({ type: SyncEntityType.SyncCompleteV1 }),
|
||||
]);
|
||||
@ -166,21 +166,21 @@ describe(SyncRequestType.AlbumAssetsV1, () => {
|
||||
await ctx.newAlbumUser({ albumId: album2.id, userId: auth.user.id, role: AlbumUserRole.Editor });
|
||||
|
||||
// should backfill the album user
|
||||
const newResponse = await ctx.syncStream(auth, [SyncRequestType.AlbumAssetsV1]);
|
||||
const newResponse = await ctx.syncStream(auth, [SyncRequestType.AlbumAssetsV2]);
|
||||
expect(newResponse).toEqual([
|
||||
{
|
||||
ack: expect.any(String),
|
||||
data: expect.objectContaining({
|
||||
id: asset1User2.id,
|
||||
}),
|
||||
type: SyncEntityType.AlbumAssetBackfillV1,
|
||||
type: SyncEntityType.AlbumAssetBackfillV2,
|
||||
},
|
||||
{
|
||||
ack: expect.any(String),
|
||||
data: expect.objectContaining({
|
||||
id: asset2User2.id,
|
||||
}),
|
||||
type: SyncEntityType.AlbumAssetBackfillV1,
|
||||
type: SyncEntityType.AlbumAssetBackfillV2,
|
||||
},
|
||||
backfillSyncAck,
|
||||
updateSyncAck,
|
||||
@ -189,13 +189,13 @@ describe(SyncRequestType.AlbumAssetsV1, () => {
|
||||
data: expect.objectContaining({
|
||||
id: asset3User2.id,
|
||||
}),
|
||||
type: SyncEntityType.AlbumAssetCreateV1,
|
||||
type: SyncEntityType.AlbumAssetCreateV2,
|
||||
},
|
||||
expect.objectContaining({ type: SyncEntityType.SyncCompleteV1 }),
|
||||
]);
|
||||
|
||||
await ctx.syncAckAll(auth, newResponse);
|
||||
await ctx.assertSyncIsComplete(auth, [SyncRequestType.AlbumAssetsV1]);
|
||||
await ctx.assertSyncIsComplete(auth, [SyncRequestType.AlbumAssetsV2]);
|
||||
});
|
||||
|
||||
it('should sync old assets when a user adds them to an album they share you', async () => {
|
||||
@ -211,7 +211,7 @@ describe(SyncRequestType.AlbumAssetsV1, () => {
|
||||
await ctx.newAlbumAsset({ albumId: album1.id, assetId: album1Asset.id });
|
||||
await ctx.newAlbumUser({ albumId: album1.id, userId: auth.user.id, role: AlbumUserRole.Editor });
|
||||
|
||||
const firstAlbumResponse = await ctx.syncStream(auth, [SyncRequestType.AlbumAssetsV1]);
|
||||
const firstAlbumResponse = await ctx.syncStream(auth, [SyncRequestType.AlbumAssetsV2]);
|
||||
expect(firstAlbumResponse).toEqual([
|
||||
updateSyncAck,
|
||||
{
|
||||
@ -219,7 +219,7 @@ describe(SyncRequestType.AlbumAssetsV1, () => {
|
||||
data: expect.objectContaining({
|
||||
id: album1Asset.id,
|
||||
}),
|
||||
type: SyncEntityType.AlbumAssetCreateV1,
|
||||
type: SyncEntityType.AlbumAssetCreateV2,
|
||||
},
|
||||
expect.objectContaining({ type: SyncEntityType.SyncCompleteV1 }),
|
||||
]);
|
||||
@ -228,14 +228,14 @@ describe(SyncRequestType.AlbumAssetsV1, () => {
|
||||
|
||||
await ctx.newAlbumUser({ albumId: album2.id, userId: auth.user.id, role: AlbumUserRole.Editor });
|
||||
|
||||
const response = await ctx.syncStream(auth, [SyncRequestType.AlbumAssetsV1]);
|
||||
const response = await ctx.syncStream(auth, [SyncRequestType.AlbumAssetsV2]);
|
||||
expect(response).toEqual([
|
||||
{
|
||||
ack: expect.any(String),
|
||||
data: expect.objectContaining({
|
||||
id: firstAsset.id,
|
||||
}),
|
||||
type: SyncEntityType.AlbumAssetBackfillV1,
|
||||
type: SyncEntityType.AlbumAssetBackfillV2,
|
||||
},
|
||||
backfillSyncAck,
|
||||
expect.objectContaining({ type: SyncEntityType.SyncCompleteV1 }),
|
||||
@ -248,7 +248,7 @@ describe(SyncRequestType.AlbumAssetsV1, () => {
|
||||
await wait(2);
|
||||
|
||||
// should backfill the new asset even though it's older than the first asset
|
||||
const newResponse = await ctx.syncStream(auth, [SyncRequestType.AlbumAssetsV1]);
|
||||
const newResponse = await ctx.syncStream(auth, [SyncRequestType.AlbumAssetsV2]);
|
||||
expect(newResponse).toEqual([
|
||||
updateSyncAck,
|
||||
{
|
||||
@ -256,13 +256,13 @@ describe(SyncRequestType.AlbumAssetsV1, () => {
|
||||
data: expect.objectContaining({
|
||||
id: secondAsset.id,
|
||||
}),
|
||||
type: SyncEntityType.AlbumAssetCreateV1,
|
||||
type: SyncEntityType.AlbumAssetCreateV2,
|
||||
},
|
||||
expect.objectContaining({ type: SyncEntityType.SyncCompleteV1 }),
|
||||
]);
|
||||
|
||||
await ctx.syncAckAll(auth, newResponse);
|
||||
await ctx.assertSyncIsComplete(auth, [SyncRequestType.AlbumAssetsV1]);
|
||||
await ctx.assertSyncIsComplete(auth, [SyncRequestType.AlbumAssetsV2]);
|
||||
});
|
||||
|
||||
it('should sync asset updates for an album shared with you', async () => {
|
||||
@ -274,7 +274,7 @@ describe(SyncRequestType.AlbumAssetsV1, () => {
|
||||
await ctx.newAlbumAsset({ albumId: album.id, assetId: asset.id });
|
||||
await ctx.newAlbumUser({ albumId: album.id, userId: auth.user.id, role: AlbumUserRole.Editor });
|
||||
|
||||
const response = await ctx.syncStream(auth, [SyncRequestType.AlbumAssetsV1]);
|
||||
const response = await ctx.syncStream(auth, [SyncRequestType.AlbumAssetsV2]);
|
||||
expect(response).toEqual([
|
||||
updateSyncAck,
|
||||
{
|
||||
@ -282,7 +282,7 @@ describe(SyncRequestType.AlbumAssetsV1, () => {
|
||||
data: expect.objectContaining({
|
||||
id: asset.id,
|
||||
}),
|
||||
type: SyncEntityType.AlbumAssetCreateV1,
|
||||
type: SyncEntityType.AlbumAssetCreateV2,
|
||||
},
|
||||
expect.objectContaining({ type: SyncEntityType.SyncCompleteV1 }),
|
||||
]);
|
||||
@ -296,7 +296,7 @@ describe(SyncRequestType.AlbumAssetsV1, () => {
|
||||
isFavorite: true,
|
||||
});
|
||||
|
||||
const updateResponse = await ctx.syncStream(auth, [SyncRequestType.AlbumAssetsV1]);
|
||||
const updateResponse = await ctx.syncStream(auth, [SyncRequestType.AlbumAssetsV2]);
|
||||
expect(updateResponse).toEqual([
|
||||
{
|
||||
ack: expect.any(String),
|
||||
@ -304,7 +304,7 @@ describe(SyncRequestType.AlbumAssetsV1, () => {
|
||||
id: asset.id,
|
||||
isFavorite: true,
|
||||
}),
|
||||
type: SyncEntityType.AlbumAssetUpdateV1,
|
||||
type: SyncEntityType.AlbumAssetUpdateV2,
|
||||
},
|
||||
expect.objectContaining({ type: SyncEntityType.SyncCompleteV1 }),
|
||||
]);
|
||||
|
||||
@ -18,7 +18,7 @@ beforeAll(async () => {
|
||||
defaultDatabase = await getKyselyDB();
|
||||
});
|
||||
|
||||
describe(SyncEntityType.AssetV1, () => {
|
||||
describe(SyncEntityType.AssetV2, () => {
|
||||
it('should detect and sync the first asset', async () => {
|
||||
const originalFileName = 'firstAsset';
|
||||
const checksum = '1115vHcVkZzNp3Q9G+FEA0nu6zUbGb4Tj4UOXkN0wRA=';
|
||||
@ -35,13 +35,13 @@ describe(SyncEntityType.AssetV1, () => {
|
||||
fileModifiedAt: date,
|
||||
localDateTime: date,
|
||||
deletedAt: null,
|
||||
duration: '0:10:00.00000',
|
||||
duration: 600_000,
|
||||
libraryId: null,
|
||||
width: 1920,
|
||||
height: 1080,
|
||||
});
|
||||
|
||||
const response = await ctx.syncStream(auth, [SyncRequestType.AssetsV1]);
|
||||
const response = await ctx.syncStream(auth, [SyncRequestType.AssetsV2]);
|
||||
expect(response).toEqual([
|
||||
{
|
||||
ack: expect.any(String),
|
||||
@ -66,13 +66,13 @@ describe(SyncEntityType.AssetV1, () => {
|
||||
height: asset.height,
|
||||
isEdited: asset.isEdited,
|
||||
},
|
||||
type: 'AssetV1',
|
||||
type: 'AssetV2',
|
||||
},
|
||||
expect.objectContaining({ type: SyncEntityType.SyncCompleteV1 }),
|
||||
]);
|
||||
|
||||
await ctx.syncAckAll(auth, response);
|
||||
await ctx.assertSyncIsComplete(auth, [SyncRequestType.AssetsV1]);
|
||||
await ctx.assertSyncIsComplete(auth, [SyncRequestType.AssetsV2]);
|
||||
});
|
||||
|
||||
it('should detect and sync a deleted asset', async () => {
|
||||
@ -81,7 +81,7 @@ describe(SyncEntityType.AssetV1, () => {
|
||||
const { asset } = await ctx.newAsset({ ownerId: auth.user.id });
|
||||
await assetRepo.remove(asset);
|
||||
|
||||
const response = await ctx.syncStream(auth, [SyncRequestType.AssetsV1]);
|
||||
const response = await ctx.syncStream(auth, [SyncRequestType.AssetsV2]);
|
||||
expect(response).toEqual([
|
||||
{
|
||||
ack: expect.any(String),
|
||||
@ -94,7 +94,7 @@ describe(SyncEntityType.AssetV1, () => {
|
||||
]);
|
||||
|
||||
await ctx.syncAckAll(auth, response);
|
||||
await ctx.assertSyncIsComplete(auth, [SyncRequestType.AssetsV1]);
|
||||
await ctx.assertSyncIsComplete(auth, [SyncRequestType.AssetsV2]);
|
||||
});
|
||||
|
||||
it('should not sync an asset or asset delete for an unrelated user', async () => {
|
||||
@ -105,17 +105,17 @@ describe(SyncEntityType.AssetV1, () => {
|
||||
const { asset } = await ctx.newAsset({ ownerId: user2.id });
|
||||
const auth2 = factory.auth({ session, user: user2 });
|
||||
|
||||
expect(await ctx.syncStream(auth2, [SyncRequestType.AssetsV1])).toEqual([
|
||||
expect.objectContaining({ type: SyncEntityType.AssetV1 }),
|
||||
expect(await ctx.syncStream(auth2, [SyncRequestType.AssetsV2])).toEqual([
|
||||
expect.objectContaining({ type: SyncEntityType.AssetV2 }),
|
||||
expect.objectContaining({ type: SyncEntityType.SyncCompleteV1 }),
|
||||
]);
|
||||
await ctx.assertSyncIsComplete(auth, [SyncRequestType.AssetsV1]);
|
||||
await ctx.assertSyncIsComplete(auth, [SyncRequestType.AssetsV2]);
|
||||
|
||||
await assetRepo.remove(asset);
|
||||
expect(await ctx.syncStream(auth2, [SyncRequestType.AssetsV1])).toEqual([
|
||||
expect(await ctx.syncStream(auth2, [SyncRequestType.AssetsV2])).toEqual([
|
||||
expect.objectContaining({ type: SyncEntityType.AssetDeleteV1 }),
|
||||
expect.objectContaining({ type: SyncEntityType.SyncCompleteV1 }),
|
||||
]);
|
||||
await ctx.assertSyncIsComplete(auth, [SyncRequestType.AssetsV1]);
|
||||
await ctx.assertSyncIsComplete(auth, [SyncRequestType.AssetsV2]);
|
||||
});
|
||||
});
|
||||
|
||||
@ -24,7 +24,7 @@ describe(SyncEntityType.SyncCompleteV1, () => {
|
||||
it('should work', async () => {
|
||||
const { auth, ctx } = await setup();
|
||||
|
||||
await ctx.assertSyncIsComplete(auth, [SyncRequestType.AssetsV1]);
|
||||
await ctx.assertSyncIsComplete(auth, [SyncRequestType.AssetsV2]);
|
||||
});
|
||||
|
||||
it('should detect an old checkpoint and send back a reset', async () => {
|
||||
@ -39,7 +39,7 @@ describe(SyncEntityType.SyncCompleteV1, () => {
|
||||
},
|
||||
]);
|
||||
|
||||
const response = await ctx.syncStream(auth, [SyncRequestType.AssetsV1]);
|
||||
const response = await ctx.syncStream(auth, [SyncRequestType.AssetsV2]);
|
||||
expect(response).toEqual([{ type: SyncEntityType.SyncResetV1, data: {}, ack: 'SyncResetV1|reset' }]);
|
||||
});
|
||||
|
||||
@ -55,6 +55,6 @@ describe(SyncEntityType.SyncCompleteV1, () => {
|
||||
},
|
||||
]);
|
||||
|
||||
await ctx.assertSyncIsComplete(auth, [SyncRequestType.AssetsV1]);
|
||||
await ctx.assertSyncIsComplete(auth, [SyncRequestType.AssetsV2]);
|
||||
});
|
||||
});
|
||||
|
||||
@ -20,7 +20,7 @@ beforeAll(async () => {
|
||||
defaultDatabase = await getKyselyDB();
|
||||
});
|
||||
|
||||
describe(SyncRequestType.PartnerAssetsV1, () => {
|
||||
describe(SyncRequestType.PartnerAssetsV2, () => {
|
||||
it('should detect and sync the first partner asset', async () => {
|
||||
const { auth, ctx } = await setup();
|
||||
|
||||
@ -39,13 +39,13 @@ describe(SyncRequestType.PartnerAssetsV1, () => {
|
||||
fileModifiedAt: date,
|
||||
localDateTime: date,
|
||||
deletedAt: null,
|
||||
duration: '0:10:00.00000',
|
||||
duration: 600_000,
|
||||
libraryId: null,
|
||||
});
|
||||
|
||||
await ctx.newPartner({ sharedById: user2.id, sharedWithId: auth.user.id });
|
||||
|
||||
const response = await ctx.syncStream(auth, [SyncRequestType.PartnerAssetsV1]);
|
||||
const response = await ctx.syncStream(auth, [SyncRequestType.PartnerAssetsV2]);
|
||||
expect(response).toEqual([
|
||||
{
|
||||
ack: expect.any(String),
|
||||
@ -70,13 +70,13 @@ describe(SyncRequestType.PartnerAssetsV1, () => {
|
||||
width: null,
|
||||
height: null,
|
||||
},
|
||||
type: SyncEntityType.PartnerAssetV1,
|
||||
type: SyncEntityType.PartnerAssetV2,
|
||||
},
|
||||
expect.objectContaining({ type: SyncEntityType.SyncCompleteV1 }),
|
||||
]);
|
||||
|
||||
await ctx.syncAckAll(auth, response);
|
||||
await ctx.assertSyncIsComplete(auth, [SyncRequestType.PartnerAssetsV1]);
|
||||
await ctx.assertSyncIsComplete(auth, [SyncRequestType.PartnerAssetsV2]);
|
||||
});
|
||||
|
||||
it('should detect and sync a deleted partner asset', async () => {
|
||||
@ -88,7 +88,7 @@ describe(SyncRequestType.PartnerAssetsV1, () => {
|
||||
await ctx.newPartner({ sharedById: user2.id, sharedWithId: auth.user.id });
|
||||
await assetRepo.remove(asset);
|
||||
|
||||
const response = await ctx.syncStream(auth, [SyncRequestType.PartnerAssetsV1]);
|
||||
const response = await ctx.syncStream(auth, [SyncRequestType.PartnerAssetsV2]);
|
||||
expect(response).toEqual([
|
||||
{
|
||||
ack: expect.any(String),
|
||||
@ -101,7 +101,7 @@ describe(SyncRequestType.PartnerAssetsV1, () => {
|
||||
]);
|
||||
|
||||
await ctx.syncAckAll(auth, response);
|
||||
await ctx.assertSyncIsComplete(auth, [SyncRequestType.PartnerAssetsV1]);
|
||||
await ctx.assertSyncIsComplete(auth, [SyncRequestType.PartnerAssetsV2]);
|
||||
});
|
||||
|
||||
it('should not sync a deleted partner asset due to a user delete', async () => {
|
||||
@ -112,7 +112,7 @@ describe(SyncRequestType.PartnerAssetsV1, () => {
|
||||
await ctx.newPartner({ sharedById: user2.id, sharedWithId: auth.user.id });
|
||||
await ctx.newAsset({ ownerId: user2.id });
|
||||
await userRepo.delete({ id: user2.id }, true);
|
||||
await ctx.assertSyncIsComplete(auth, [SyncRequestType.PartnerAssetsV1]);
|
||||
await ctx.assertSyncIsComplete(auth, [SyncRequestType.PartnerAssetsV2]);
|
||||
});
|
||||
|
||||
it('should not sync a deleted partner asset due to a partner delete (unshare)', async () => {
|
||||
@ -122,12 +122,12 @@ describe(SyncRequestType.PartnerAssetsV1, () => {
|
||||
const { user: user2 } = await ctx.newUser();
|
||||
await ctx.newAsset({ ownerId: user2.id });
|
||||
const { partner } = await ctx.newPartner({ sharedById: user2.id, sharedWithId: auth.user.id });
|
||||
await expect(ctx.syncStream(auth, [SyncRequestType.PartnerAssetsV1])).resolves.toEqual([
|
||||
expect.objectContaining({ type: SyncEntityType.PartnerAssetV1 }),
|
||||
await expect(ctx.syncStream(auth, [SyncRequestType.PartnerAssetsV2])).resolves.toEqual([
|
||||
expect.objectContaining({ type: SyncEntityType.PartnerAssetV2 }),
|
||||
expect.objectContaining({ type: SyncEntityType.SyncCompleteV1 }),
|
||||
]);
|
||||
await partnerRepo.remove(partner);
|
||||
await ctx.assertSyncIsComplete(auth, [SyncRequestType.PartnerAssetsV1]);
|
||||
await ctx.assertSyncIsComplete(auth, [SyncRequestType.PartnerAssetsV2]);
|
||||
});
|
||||
|
||||
it('should not sync an asset or asset delete for own user', async () => {
|
||||
@ -138,19 +138,19 @@ describe(SyncRequestType.PartnerAssetsV1, () => {
|
||||
const { asset } = await ctx.newAsset({ ownerId: auth.user.id });
|
||||
await ctx.newPartner({ sharedById: user2.id, sharedWithId: auth.user.id });
|
||||
|
||||
await expect(ctx.syncStream(auth, [SyncRequestType.AssetsV1])).resolves.toEqual([
|
||||
expect.objectContaining({ type: SyncEntityType.AssetV1 }),
|
||||
await expect(ctx.syncStream(auth, [SyncRequestType.AssetsV2])).resolves.toEqual([
|
||||
expect.objectContaining({ type: SyncEntityType.AssetV2 }),
|
||||
expect.objectContaining({ type: SyncEntityType.SyncCompleteV1 }),
|
||||
]);
|
||||
await ctx.assertSyncIsComplete(auth, [SyncRequestType.PartnerAssetsV1]);
|
||||
await ctx.assertSyncIsComplete(auth, [SyncRequestType.PartnerAssetsV2]);
|
||||
|
||||
await assetRepo.remove(asset);
|
||||
|
||||
await expect(ctx.syncStream(auth, [SyncRequestType.AssetsV1])).resolves.toEqual([
|
||||
await expect(ctx.syncStream(auth, [SyncRequestType.AssetsV2])).resolves.toEqual([
|
||||
expect.objectContaining({ type: SyncEntityType.AssetDeleteV1 }),
|
||||
expect.objectContaining({ type: SyncEntityType.SyncCompleteV1 }),
|
||||
]);
|
||||
await ctx.assertSyncIsComplete(auth, [SyncRequestType.PartnerAssetsV1]);
|
||||
await ctx.assertSyncIsComplete(auth, [SyncRequestType.PartnerAssetsV2]);
|
||||
});
|
||||
|
||||
it('should not sync an asset or asset delete for unrelated user', async () => {
|
||||
@ -162,19 +162,19 @@ describe(SyncRequestType.PartnerAssetsV1, () => {
|
||||
const { asset } = await ctx.newAsset({ ownerId: user2.id });
|
||||
const auth2 = factory.auth({ session, user: user2 });
|
||||
|
||||
await expect(ctx.syncStream(auth2, [SyncRequestType.AssetsV1])).resolves.toEqual([
|
||||
expect.objectContaining({ type: SyncEntityType.AssetV1 }),
|
||||
await expect(ctx.syncStream(auth2, [SyncRequestType.AssetsV2])).resolves.toEqual([
|
||||
expect.objectContaining({ type: SyncEntityType.AssetV2 }),
|
||||
expect.objectContaining({ type: SyncEntityType.SyncCompleteV1 }),
|
||||
]);
|
||||
await ctx.assertSyncIsComplete(auth, [SyncRequestType.PartnerAssetsV1]);
|
||||
await ctx.assertSyncIsComplete(auth, [SyncRequestType.PartnerAssetsV2]);
|
||||
|
||||
await assetRepo.remove(asset);
|
||||
|
||||
await expect(ctx.syncStream(auth2, [SyncRequestType.AssetsV1])).resolves.toEqual([
|
||||
await expect(ctx.syncStream(auth2, [SyncRequestType.AssetsV2])).resolves.toEqual([
|
||||
expect.objectContaining({ type: SyncEntityType.AssetDeleteV1 }),
|
||||
expect.objectContaining({ type: SyncEntityType.SyncCompleteV1 }),
|
||||
]);
|
||||
await ctx.assertSyncIsComplete(auth, [SyncRequestType.PartnerAssetsV1]);
|
||||
await ctx.assertSyncIsComplete(auth, [SyncRequestType.PartnerAssetsV2]);
|
||||
});
|
||||
|
||||
it('should backfill partner assets when a partner shared their library with you', async () => {
|
||||
@ -187,14 +187,14 @@ describe(SyncRequestType.PartnerAssetsV1, () => {
|
||||
const { asset: assetUser2 } = await ctx.newAsset({ ownerId: user2.id });
|
||||
await ctx.newPartner({ sharedById: user2.id, sharedWithId: auth.user.id });
|
||||
|
||||
const response = await ctx.syncStream(auth, [SyncRequestType.PartnerAssetsV1]);
|
||||
const response = await ctx.syncStream(auth, [SyncRequestType.PartnerAssetsV2]);
|
||||
expect(response).toEqual([
|
||||
{
|
||||
ack: expect.any(String),
|
||||
data: expect.objectContaining({
|
||||
id: assetUser2.id,
|
||||
}),
|
||||
type: SyncEntityType.PartnerAssetV1,
|
||||
type: SyncEntityType.PartnerAssetV2,
|
||||
},
|
||||
expect.objectContaining({ type: SyncEntityType.SyncCompleteV1 }),
|
||||
]);
|
||||
@ -202,17 +202,17 @@ describe(SyncRequestType.PartnerAssetsV1, () => {
|
||||
await ctx.syncAckAll(auth, response);
|
||||
await ctx.newPartner({ sharedById: user3.id, sharedWithId: auth.user.id });
|
||||
|
||||
const newResponse = await ctx.syncStream(auth, [SyncRequestType.PartnerAssetsV1]);
|
||||
const newResponse = await ctx.syncStream(auth, [SyncRequestType.PartnerAssetsV2]);
|
||||
expect(newResponse).toEqual([
|
||||
{
|
||||
ack: expect.any(String),
|
||||
data: expect.objectContaining({
|
||||
id: assetUser3.id,
|
||||
}),
|
||||
type: SyncEntityType.PartnerAssetBackfillV1,
|
||||
type: SyncEntityType.PartnerAssetBackfillV2,
|
||||
},
|
||||
{
|
||||
ack: expect.stringContaining(SyncEntityType.PartnerAssetBackfillV1),
|
||||
ack: expect.stringContaining(SyncEntityType.PartnerAssetBackfillV2),
|
||||
data: {},
|
||||
type: SyncEntityType.SyncAckV1,
|
||||
},
|
||||
@ -220,7 +220,7 @@ describe(SyncRequestType.PartnerAssetsV1, () => {
|
||||
]);
|
||||
|
||||
await ctx.syncAckAll(auth, newResponse);
|
||||
await ctx.assertSyncIsComplete(auth, [SyncRequestType.PartnerAssetsV1]);
|
||||
await ctx.assertSyncIsComplete(auth, [SyncRequestType.PartnerAssetsV2]);
|
||||
});
|
||||
|
||||
it('should only backfill partner assets created prior to the current partner asset checkpoint', async () => {
|
||||
@ -235,31 +235,31 @@ describe(SyncRequestType.PartnerAssetsV1, () => {
|
||||
const { asset: asset2User3 } = await ctx.newAsset({ ownerId: user3.id });
|
||||
await ctx.newPartner({ sharedById: user2.id, sharedWithId: auth.user.id });
|
||||
|
||||
const response = await ctx.syncStream(auth, [SyncRequestType.PartnerAssetsV1]);
|
||||
const response = await ctx.syncStream(auth, [SyncRequestType.PartnerAssetsV2]);
|
||||
expect(response).toEqual([
|
||||
{
|
||||
ack: expect.any(String),
|
||||
data: expect.objectContaining({
|
||||
id: assetUser2.id,
|
||||
}),
|
||||
type: SyncEntityType.PartnerAssetV1,
|
||||
type: SyncEntityType.PartnerAssetV2,
|
||||
},
|
||||
expect.objectContaining({ type: SyncEntityType.SyncCompleteV1 }),
|
||||
]);
|
||||
await ctx.syncAckAll(auth, response);
|
||||
|
||||
await ctx.newPartner({ sharedById: user3.id, sharedWithId: auth.user.id });
|
||||
const newResponse = await ctx.syncStream(auth, [SyncRequestType.PartnerAssetsV1]);
|
||||
const newResponse = await ctx.syncStream(auth, [SyncRequestType.PartnerAssetsV2]);
|
||||
expect(newResponse).toEqual([
|
||||
{
|
||||
ack: expect.any(String),
|
||||
data: expect.objectContaining({
|
||||
id: assetUser3.id,
|
||||
}),
|
||||
type: SyncEntityType.PartnerAssetBackfillV1,
|
||||
type: SyncEntityType.PartnerAssetBackfillV2,
|
||||
},
|
||||
{
|
||||
ack: expect.stringContaining(SyncEntityType.PartnerAssetBackfillV1),
|
||||
ack: expect.stringContaining(SyncEntityType.PartnerAssetBackfillV2),
|
||||
data: {},
|
||||
type: SyncEntityType.SyncAckV1,
|
||||
},
|
||||
@ -268,12 +268,12 @@ describe(SyncRequestType.PartnerAssetsV1, () => {
|
||||
data: expect.objectContaining({
|
||||
id: asset2User3.id,
|
||||
}),
|
||||
type: SyncEntityType.PartnerAssetV1,
|
||||
type: SyncEntityType.PartnerAssetV2,
|
||||
},
|
||||
expect.objectContaining({ type: SyncEntityType.SyncCompleteV1 }),
|
||||
]);
|
||||
|
||||
await ctx.syncAckAll(auth, newResponse);
|
||||
await ctx.assertSyncIsComplete(auth, [SyncRequestType.PartnerAssetsV1]);
|
||||
await ctx.assertSyncIsComplete(auth, [SyncRequestType.PartnerAssetsV2]);
|
||||
});
|
||||
});
|
||||
|
||||
@ -21,7 +21,7 @@ describe(SyncEntityType.SyncResetV1, () => {
|
||||
it('should work', async () => {
|
||||
const { auth, ctx } = await setup();
|
||||
|
||||
await ctx.assertSyncIsComplete(auth, [SyncRequestType.AssetsV1]);
|
||||
await ctx.assertSyncIsComplete(auth, [SyncRequestType.AssetsV2]);
|
||||
});
|
||||
|
||||
it('should detect a pending sync reset', async () => {
|
||||
@ -31,7 +31,7 @@ describe(SyncEntityType.SyncResetV1, () => {
|
||||
isPendingSyncReset: true,
|
||||
});
|
||||
|
||||
const response = await ctx.syncStream(auth, [SyncRequestType.AssetsV1]);
|
||||
const response = await ctx.syncStream(auth, [SyncRequestType.AssetsV2]);
|
||||
expect(response).toEqual([{ type: SyncEntityType.SyncResetV1, data: {}, ack: 'SyncResetV1|reset' }]);
|
||||
});
|
||||
|
||||
@ -40,8 +40,8 @@ describe(SyncEntityType.SyncResetV1, () => {
|
||||
|
||||
await ctx.newAsset({ ownerId: user.id });
|
||||
|
||||
await expect(ctx.syncStream(auth, [SyncRequestType.AssetsV1])).resolves.toEqual([
|
||||
expect.objectContaining({ type: SyncEntityType.AssetV1 }),
|
||||
await expect(ctx.syncStream(auth, [SyncRequestType.AssetsV2])).resolves.toEqual([
|
||||
expect.objectContaining({ type: SyncEntityType.AssetV2 }),
|
||||
expect.objectContaining({ type: SyncEntityType.SyncCompleteV1 }),
|
||||
]);
|
||||
|
||||
@ -49,7 +49,7 @@ describe(SyncEntityType.SyncResetV1, () => {
|
||||
isPendingSyncReset: true,
|
||||
});
|
||||
|
||||
await expect(ctx.syncStream(auth, [SyncRequestType.AssetsV1])).resolves.toEqual([
|
||||
await expect(ctx.syncStream(auth, [SyncRequestType.AssetsV2])).resolves.toEqual([
|
||||
{ type: SyncEntityType.SyncResetV1, data: {}, ack: 'SyncResetV1|reset' },
|
||||
]);
|
||||
});
|
||||
@ -63,8 +63,8 @@ describe(SyncEntityType.SyncResetV1, () => {
|
||||
isPendingSyncReset: true,
|
||||
});
|
||||
|
||||
await expect(ctx.syncStream(auth, [SyncRequestType.AssetsV1], true)).resolves.toEqual([
|
||||
expect.objectContaining({ type: SyncEntityType.AssetV1 }),
|
||||
await expect(ctx.syncStream(auth, [SyncRequestType.AssetsV2], true)).resolves.toEqual([
|
||||
expect.objectContaining({ type: SyncEntityType.AssetV2 }),
|
||||
expect.objectContaining({ type: SyncEntityType.SyncCompleteV1 }),
|
||||
]);
|
||||
});
|
||||
@ -74,20 +74,20 @@ describe(SyncEntityType.SyncResetV1, () => {
|
||||
|
||||
await ctx.newAsset({ ownerId: user.id });
|
||||
|
||||
const response = await ctx.syncStream(auth, [SyncRequestType.AssetsV1]);
|
||||
const response = await ctx.syncStream(auth, [SyncRequestType.AssetsV2]);
|
||||
await ctx.syncAckAll(auth, response);
|
||||
|
||||
await ctx.get(SessionRepository).update(auth.session!.id, {
|
||||
isPendingSyncReset: true,
|
||||
});
|
||||
|
||||
const resetResponse = await ctx.syncStream(auth, [SyncRequestType.AssetsV1]);
|
||||
const resetResponse = await ctx.syncStream(auth, [SyncRequestType.AssetsV2]);
|
||||
|
||||
await ctx.syncAckAll(auth, resetResponse);
|
||||
|
||||
const postResetResponse = await ctx.syncStream(auth, [SyncRequestType.AssetsV1]);
|
||||
const postResetResponse = await ctx.syncStream(auth, [SyncRequestType.AssetsV2]);
|
||||
expect(postResetResponse).toEqual([
|
||||
expect.objectContaining({ type: SyncEntityType.AssetV1 }),
|
||||
expect.objectContaining({ type: SyncEntityType.AssetV2 }),
|
||||
expect.objectContaining({ type: SyncEntityType.SyncCompleteV1 }),
|
||||
]);
|
||||
});
|
||||
|
||||
@ -50,7 +50,7 @@ describe('utils', () => {
|
||||
originalPath: 'image.gif',
|
||||
originalMimeType: 'image/gif',
|
||||
type: AssetTypeEnum.Image,
|
||||
duration: '2.0',
|
||||
duration: 2000,
|
||||
});
|
||||
|
||||
const url = getAssetUrl({ asset });
|
||||
@ -65,7 +65,7 @@ describe('utils', () => {
|
||||
originalPath: 'image.webp',
|
||||
originalMimeType: 'image/webp',
|
||||
type: AssetTypeEnum.Image,
|
||||
duration: '2.0',
|
||||
duration: 2000,
|
||||
});
|
||||
|
||||
const url = getAssetUrl({ asset });
|
||||
@ -119,7 +119,7 @@ describe('utils', () => {
|
||||
originalPath: 'image.gif',
|
||||
originalMimeType: 'image/gif',
|
||||
type: AssetTypeEnum.Image,
|
||||
duration: '2.0',
|
||||
duration: 2000,
|
||||
});
|
||||
const sharedLink = sharedLinkFactory.build({ allowDownload: true, showMetadata: true, assets: [asset] });
|
||||
|
||||
@ -134,7 +134,7 @@ describe('utils', () => {
|
||||
originalPath: 'image.gif',
|
||||
originalMimeType: 'image/gif',
|
||||
type: AssetTypeEnum.Image,
|
||||
duration: '2.0',
|
||||
duration: 2000,
|
||||
});
|
||||
const sharedLink = sharedLinkFactory.build({ allowDownload: false, assets: [asset] });
|
||||
|
||||
@ -150,7 +150,7 @@ describe('utils', () => {
|
||||
originalPath: 'image.gif',
|
||||
originalMimeType: 'image/gif',
|
||||
type: AssetTypeEnum.Image,
|
||||
duration: '2.0',
|
||||
duration: 2000,
|
||||
});
|
||||
const sharedLink = sharedLinkFactory.build({ showMetadata: false, assets: [asset] });
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user