Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@
"@inquirer/prompts": "8.7.3",
"@internxt/inxt-js": "3.3.5",
"@internxt/lib": "1.5.2",
"@internxt/sdk": "1.22.1",
"@internxt/sdk": "1.24.0",
"@oclif/core": "5.1.8",
"@oclif/plugin-autocomplete": "4.0.4",
"axios": "1.20.0",
Expand Down
13 changes: 1 addition & 12 deletions src/services/drive/drive-folder.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -108,18 +108,7 @@ export class DriveFolderService {
const existentFolder = existentFolders[0];
if (!existentFolder) return undefined;

return {
itemType: 'folder',
uuid: existentFolder.uuid,
bucket: existentFolder.bucket,
status: existentFolder.deleted ? FileStatus.TRASHED : FileStatus.EXISTS,
name: existentFolder.plainName ?? '',
parentUuid: existentFolder.parentUuid,
createdAt: new Date(existentFolder.createdAt),
updatedAt: new Date(existentFolder.updatedAt),
creationTime: new Date(existentFolder.createdAt),
modificationTime: new Date(existentFolder.updatedAt),
};
return DriveUtils.driveFolderMetaToItem(existentFolder);
};

public renameFolder = async (payload: { folderUuid: string; name: string }): Promise<void> => {
Expand Down
4 changes: 2 additions & 2 deletions src/types/drive.types.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { FileMeta, FolderMeta } from '@internxt/sdk/dist/drive/storage/types';
import { FileMeta, FileStatus, FolderMeta } from '@internxt/sdk/dist/drive/storage/types';

export type DriveItemType = 'file' | 'folder';

Expand All @@ -19,7 +19,7 @@ export type DriveFolderItem = Pick<FolderMeta, 'uuid' | 'name' | 'bucket'> & {
updatedAt: Date;
creationTime: Date;
modificationTime: Date;
status: 'EXISTS' | 'TRASHED';
status: `${FileStatus}`;
parentUuid: string | null;
};

Expand Down
19 changes: 13 additions & 6 deletions src/utils/drive.utils.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,10 @@
import { FileMeta, FolderMeta, CreateFolderResponse, FileStatus } from '@internxt/sdk/dist/drive/storage/types';
import {
CreateFolderResponse,
FetchFolderByPathResponse,
FetchFolderMetaResponse,
FileMeta,
FileStatus,
} from '@internxt/sdk/dist/drive/storage/types';
import { DriveFileItem, DriveFolderItem, DriveItemType } from '../types/drive.types';
import { ServiceUnavailableError } from './errors.utils';

Expand Down Expand Up @@ -35,19 +41,19 @@ export class DriveUtils {
};
}

static driveFolderMetaToItem(folderMeta: FolderMeta): DriveFolderItem {
static driveFolderMetaToItem(folderMeta: FetchFolderMetaResponse | FetchFolderByPathResponse): DriveFolderItem {
DriveUtils.assertUsableMeta(folderMeta, 'folder');
return {
itemType: 'folder',
uuid: folderMeta.uuid,
bucket: folderMeta.bucket,
status: folderMeta.deleted || folderMeta.removed ? FileStatus.TRASHED : FileStatus.EXISTS,
status: folderMeta.status,
name: folderMeta.plainName,
parentUuid: folderMeta.parentUuid,
createdAt: new Date(folderMeta.createdAt),
updatedAt: new Date(folderMeta.updatedAt),
creationTime: new Date(folderMeta.creation_time),
modificationTime: new Date(folderMeta.creation_time),
creationTime: new Date(folderMeta.creationTime),
modificationTime: new Date(folderMeta.modificationTime),
};
}

Expand All @@ -56,7 +62,8 @@ export class DriveUtils {
itemType: 'folder',
uuid: folderResponse.uuid,
bucket: folderResponse.bucket,
status: folderResponse.deleted || folderResponse.removed ? FileStatus.TRASHED : FileStatus.EXISTS,
// The SDK's create response type has no status; a new folder always exists.
status: FileStatus.EXISTS,
name: folderResponse.plainName,
parentUuid: folderResponse.parentUuid,
createdAt: new Date(folderResponse.createdAt),
Expand Down
2 changes: 1 addition & 1 deletion src/webdav/handlers/PROPFIND.handler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ export class PROPFINDRequestHandler implements WebDavMethodHandler {
itemType: 'folder',
name: folder.plainName,
bucket: folder.bucket,
status: folder.deleted || folder.removed ? 'TRASHED' : 'EXISTS',
status: folder.status,
createdAt: new Date(folder.createdAt),
updatedAt: new Date(folder.updatedAt),
creationTime: new Date(folder.creationTime),
Expand Down
49 changes: 18 additions & 31 deletions test/fixtures/drive.fixture.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import {
CreateFolderResponse,
FetchFolderMetaResponse,
EncryptionVersion,
FetchPaginatedFile,
FetchPaginatedFolder,
FileMeta,
FileStatus,
FolderMeta,
} from '@internxt/sdk/dist/drive/storage/types';
import { getDefaultWordlist, wordlists } from 'bip39';
import crypto, { randomInt, randomUUID } from 'node:crypto';
Expand Down Expand Up @@ -53,40 +53,27 @@ export const newFileItem = (attributes?: Partial<DriveFileItem>): DriveFileItem
return { ...file, ...attributes };
};

export const newFolderMeta = (attributes?: Partial<FolderMeta>): FolderMeta => {
const createdAt = getRandomDate();
const updatedAt = getRandomDate();
const folder: FolderMeta = {
bucket: crypto.randomBytes(16).toString('hex'),
createdAt: createdAt.toString(),
created_at: createdAt.toString(),
deleted: false,
deletedAt: null,
deleted_at: null,
encryptVersion: EncryptionVersion.Aes03,
encrypt_version: EncryptionVersion.Aes03,
export const newFolderMeta = (attributes?: Partial<FetchFolderMetaResponse>): FetchFolderMetaResponse => {
const folder: FetchFolderMetaResponse = {
type: 'folder',
id: randomInt(1, 100000),
name: crypto.randomBytes(16).toString('hex'),
parent: null,
parentId: randomInt(1, 100000),
parent_id: randomInt(1, 100000),
plainName: wordlist[randomInt(wordlist.length)],
plain_name: wordlist[randomInt(wordlist.length)],
removed: false,
removedAt: null,
removed_at: null,
size: randomInt(1, 10000),
type: 'folder',
updatedAt: updatedAt.toString(),
updated_at: updatedAt.toString(),
user: null,
parentUuid: randomUUID(),
name: crypto.randomBytes(16).toString('hex'),
parent: {},
bucket: crypto.randomBytes(16).toString('hex'),
userId: randomInt(1, 100000),
user_id: randomInt(1, 100000),
encryptVersion: EncryptionVersion.Aes03,
createdAt: getRandomDate().toISOString(),
updatedAt: getRandomDate().toISOString(),
uuid: randomUUID(),
parentUuid: randomUUID(),
parent_uuid: randomUUID(),
creation_time: getRandomDate().toString(),
modification_time: getRandomDate().toString(),
plainName: wordlist[randomInt(wordlist.length)],
size: randomInt(1, 10000),
creationTime: getRandomDate().toISOString(),
modificationTime: getRandomDate().toISOString(),
status: FileStatus.EXISTS,
removed: false,
deleted: false,
};
return { ...folder, ...attributes };
};
Expand Down
22 changes: 15 additions & 7 deletions test/services/drive/drive-folder.service.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,9 @@ import { DriveUtils } from '../../../src/utils/drive.utils';
import { generateSubcontent, newCreateFolderResponse, newFolderMeta, pageOf } from '../../fixtures/drive.fixture';
import {
CreateFolderResponse,
FolderMeta,
CheckDuplicatedFoldersResponse,
FetchFolderByPathResponse,
FetchFolderMetaResponse,
FileStatus,
} from '@internxt/sdk/dist/drive/storage/types';
import { ConfigService } from '../../../src/services/config.service';
import { UserCredentialsFixture } from '../../fixtures/login.fixture';
Expand Down Expand Up @@ -124,10 +125,10 @@ describe('Drive Folder Service', () => {
});

test('when a folder with the given name exists in the parent, then it is returned as a folder item', async () => {
const existentFolder = newCreateFolderResponse({ plainName: 'backup', uuid: 'backup-uuid' });
const existentFolder = newFolderMeta({ plainName: 'backup', uuid: 'backup-uuid' });
const spy = vi
.spyOn(Storage.prototype, 'checkDuplicatedFolders')
.mockResolvedValue({ existentFolders: [existentFolder] } as unknown as CheckDuplicatedFoldersResponse);
.mockResolvedValue({ existentFolders: [existentFolder] });
vi.spyOn(SdkManager.instance, 'getStorage').mockReturnValue(Storage.prototype);

const result = await sut.findExistentFolder('parent-uuid', 'backup');
Expand All @@ -144,21 +145,28 @@ describe('Drive Folder Service', () => {
});

test('when the API answers a path lookup with an empty body, then a retryable error is thrown', async () => {
vi.spyOn(Storage.prototype, 'getFolderByPath').mockResolvedValue('' as unknown as FolderMeta);
vi.spyOn(Storage.prototype, 'getFolderByPath').mockResolvedValue('' as unknown as FetchFolderByPathResponse);
vi.spyOn(SdkManager.instance, 'getStorage').mockReturnValue(Storage.prototype);

await expect(sut.getFolderMetaByPath('/a/b/')).rejects.toBeInstanceOf(ServiceUnavailableError);
});

test('when a path lookup answers with a trashed folder, then a not found error is thrown', async () => {
vi.spyOn(Storage.prototype, 'getFolderByPath').mockResolvedValue(newFolderMeta({ removed: true }));
vi.spyOn(Storage.prototype, 'getFolderByPath').mockResolvedValue(newFolderMeta({ status: FileStatus.TRASHED }));
vi.spyOn(SdkManager.instance, 'getStorage').mockReturnValue(Storage.prototype);

await expect(sut.getFolderMetaByPath('/a/b/')).rejects.toBeInstanceOf(NotFoundError);
});

test('when a uuid lookup answers with a trashed folder, then a not found error is thrown', async () => {
vi.spyOn(Storage.prototype, 'getFolderMeta').mockResolvedValue(newFolderMeta({ status: FileStatus.TRASHED }));
vi.spyOn(SdkManager.instance, 'getStorage').mockReturnValue(Storage.prototype);

await expect(sut.getFolderMetaByUuid(randomUUID())).rejects.toBeInstanceOf(NotFoundError);
});

test('when the API answers a uuid lookup with an empty body, then a retryable error is thrown', async () => {
vi.spyOn(Storage.prototype, 'getFolderMeta').mockResolvedValue('' as unknown as FolderMeta);
vi.spyOn(Storage.prototype, 'getFolderMeta').mockResolvedValue('' as unknown as FetchFolderMetaResponse);
vi.spyOn(SdkManager.instance, 'getStorage').mockReturnValue(Storage.prototype);

await expect(sut.getFolderMetaByUuid(randomUUID())).rejects.toBeInstanceOf(ServiceUnavailableError);
Expand Down
Loading