chore!: duration in milliseconds (#28003)

* server changes

* openapi

* web changes

* mobile changes

* assume 3.0 client

* deprecate

* review feedback

* update medium tests

* linting
This commit is contained in:
Mert
2026-04-30 09:44:27 -04:00
committed by GitHub
parent 97c62136b7
commit b554664791
44 changed files with 1092 additions and 335 deletions
@@ -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 }),
]);