Merge branch 'main' into feat/hero_view_transitions

This commit is contained in:
Alex
2026-05-10 22:36:28 -05:00
committed by GitHub
178 changed files with 17012 additions and 2087 deletions
-1
View File
@@ -1 +0,0 @@
24.15.0
+15
View File
@@ -27,3 +27,18 @@ run = { task = "lint --fix" }
[tasks.check]
env._.path = "./node_modules/.bin"
run = "tsc --noEmit"
[tasks.ci-setup]
depends = ["//:sdk:install", "//:sdk:build", "//cli:install", "//cli:build"]
run = { task = ":install" }
[tasks.ci-unit]
depends = ["//:sdk:install", "//:sdk:build"]
run = [
{ task = ":install" },
{ task = ":format" },
{ task = ":lint" },
{ task = ":check" },
]
-3
View File
@@ -56,8 +56,5 @@
"utimes": "^5.2.1",
"vite-tsconfig-paths": "^6.1.1",
"vitest": "^4.0.0"
},
"volta": {
"node": "24.15.0"
}
}
+74 -10
View File
@@ -146,7 +146,7 @@ describe('/albums', () => {
it('should not return shared albums with a deleted owner', async () => {
const { status, body } = await request(app)
.get('/albums?shared=true')
.get('/albums?isShared=true')
.set('Authorization', `Bearer ${user1.accessToken}`);
expect(status).toBe(200);
@@ -188,7 +188,7 @@ describe('/albums', () => {
it('should return the album collection including owned and shared', async () => {
const { status, body } = await request(app).get('/albums').set('Authorization', `Bearer ${user1.accessToken}`);
expect(status).toBe(200);
expect(body).toHaveLength(4);
expect(body).toHaveLength(5);
expect(body).toEqual(
expect.arrayContaining([
expect.objectContaining({
@@ -219,13 +219,20 @@ describe('/albums', () => {
]),
shared: false,
}),
expect.objectContaining({
albumName: user2SharedUser,
albumUsers: expect.arrayContaining([
{ role: AlbumUserRole.Owner, user: expect.objectContaining({ id: user2.userId }) },
]),
shared: true,
}),
]),
);
});
it('should return the album collection filtered by shared', async () => {
it('should return the album collection filtered by isShared', async () => {
const { status, body } = await request(app)
.get('/albums?shared=true')
.get('/albums?isShared=true')
.set('Authorization', `Bearer ${user1.accessToken}`);
expect(status).toBe(200);
expect(body).toHaveLength(4);
@@ -263,9 +270,9 @@ describe('/albums', () => {
);
});
it('should return the album collection filtered by NOT shared', async () => {
it('should return the album collection filtered by NOT isShared', async () => {
const { status, body } = await request(app)
.get('/albums?shared=false')
.get('/albums?isShared=false')
.set('Authorization', `Bearer ${user1.accessToken}`);
expect(status).toBe(200);
expect(body).toHaveLength(1);
@@ -282,6 +289,63 @@ describe('/albums', () => {
);
});
it('should return only owned albums when filtered by isOwned=true', async () => {
const { status, body } = await request(app)
.get('/albums?isOwned=true')
.set('Authorization', `Bearer ${user1.accessToken}`);
expect(status).toBe(200);
expect(body).toHaveLength(4);
expect(body).toEqual(
expect.arrayContaining([
expect.objectContaining({ albumName: user1SharedEditorUser }),
expect.objectContaining({ albumName: user1SharedViewerUser }),
expect.objectContaining({ albumName: user1SharedLink }),
expect.objectContaining({ albumName: user1NotShared }),
]),
);
});
it('should return only shared-with-me albums when filtered by isOwned=false', async () => {
const { status, body } = await request(app)
.get('/albums?isOwned=false')
.set('Authorization', `Bearer ${user1.accessToken}`);
expect(status).toBe(200);
expect(body).toHaveLength(1);
expect(body).toEqual(
expect.arrayContaining([
expect.objectContaining({
albumName: user2SharedUser,
albumUsers: expect.arrayContaining([
{ role: AlbumUserRole.Owner, user: expect.objectContaining({ id: user2.userId }) },
]),
}),
]),
);
});
it('should return owned shared-out albums when filtered by isOwned=true&ishared=true', async () => {
const { status, body } = await request(app)
.get('/albums?isOwned=true&isShared=true')
.set('Authorization', `Bearer ${user1.accessToken}`);
expect(status).toBe(200);
expect(body).toHaveLength(3);
expect(body).toEqual(
expect.arrayContaining([
expect.objectContaining({ albumName: user1SharedEditorUser }),
expect.objectContaining({ albumName: user1SharedViewerUser }),
expect.objectContaining({ albumName: user1SharedLink }),
]),
);
});
it('should return empty list when filtered by isOwned=false&isShared=false', async () => {
const { status, body } = await request(app)
.get('/albums?isOwned=false&isShared=false')
.set('Authorization', `Bearer ${user1.accessToken}`);
expect(status).toBe(200);
expect(body).toHaveLength(0);
});
it('should return the album collection filtered by assetId', async () => {
const { status, body } = await request(app)
.get(`/albums?assetId=${user1Asset2.id}`)
@@ -290,17 +354,17 @@ describe('/albums', () => {
expect(body).toHaveLength(2);
});
it('should return the album collection filtered by assetId and ignores shared=true', async () => {
it('should return the album collection filtered by assetId and ignores isShared=true', async () => {
const { status, body } = await request(app)
.get(`/albums?shared=true&assetId=${user1Asset1.id}`)
.get(`/albums?isShared=true&assetId=${user1Asset1.id}`)
.set('Authorization', `Bearer ${user1.accessToken}`);
expect(status).toBe(200);
expect(body).toHaveLength(5);
});
it('should return the album collection filtered by assetId and ignores shared=false', async () => {
it('should return the album collection filtered by assetId and ignores isShared=false', async () => {
const { status, body } = await request(app)
.get(`/albums?shared=false&assetId=${user1Asset1.id}`)
.get(`/albums?isShared=false&assetId=${user1Asset1.id}`)
.set('Authorization', `Bearer ${user1.accessToken}`);
expect(status).toBe(200);
expect(body).toHaveLength(5);
+2 -1
View File
@@ -240,7 +240,8 @@ export const setupBaseMockApiRoutes = async (context: BrowserContext, adminUserI
});
});
await context.route('**/api/albums*', async (route, request) => {
if (request.url().endsWith('albums?shared=true') || request.url().endsWith('albums')) {
const url = request.url();
if (url.endsWith('albums?isShared=true') || url.endsWith('albums?isOwned=true') || url.endsWith('albums')) {
return route.fulfill({
status: 200,
contentType: 'application/json',