Skip to content

Commit

Permalink
refactor test cases
Browse files Browse the repository at this point in the history
  • Loading branch information
TheodoreKrypton committed Apr 21, 2024
1 parent 8060962 commit a948e0d
Show file tree
Hide file tree
Showing 15 changed files with 389 additions and 319 deletions.
4 changes: 2 additions & 2 deletions src/api/client/file-api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ export class FileApi extends DirectoryApi {
private async createFile(where: TGFSDirectory, fileMsg: GeneralFileMessage) {
validateName(fileMsg.name);

const id = await this.createFileDesc(fileMsg);
const fr = where.createFileRef(fileMsg.name, id);
const messageId = await this.createFileDesc(fileMsg);
const fr = where.createFileRef(fileMsg.name, messageId);

await this.syncMetadata();

Expand Down
13 changes: 6 additions & 7 deletions src/api/client/message-api/file-uploader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,15 +64,14 @@ export abstract class FileUploader<T extends GeneralFileMessage> {
this.uploaded + this.chunkSize > this.fileSize
? this.fileSize - this.uploaded
: this.chunkSize;
this.uploaded += chunkLength;
this.partCnt += 1;

const chunk = await this.read(chunkLength);

if (chunk === null) {
if (chunkLength === 0) {
return 0;
}

this.uploaded += chunkLength;
this.partCnt += 1;
const chunk = await this.read(chunkLength);

let retry = 3;
while (retry) {
Expand Down Expand Up @@ -133,8 +132,8 @@ export abstract class FileUploader<T extends GeneralFileMessage> {
const createWorker = async (workerId: number): Promise<boolean> => {
try {
while (!this.done()) {
await this.uploadNextPart(workerId);
if (callback) {
const partSize = await this.uploadNextPart(workerId);
if (partSize && callback) {
Logger.info(
`[worker ${workerId}] ${
(this.uploaded * 100) / this.fileSize
Expand Down
2 changes: 2 additions & 0 deletions src/api/client/metadata-api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,13 +50,15 @@ export class MetaDataApi extends FileDescApi {
protected async updateMetadata(): Promise<undefined> {
const buffer = Buffer.from(JSON.stringify(this.metadata.toObject()));
if (this.metadata.msgId) {
// update current metadata
await this.editMessageMedia(
this.metadata.msgId,
buffer,
'metadata.json',
'',
);
} else {
// doesn't exist, create new metadata and pin
const messageId = await this.sendFile({ buffer, name: 'metadata.json' });
this.metadata.msgId = messageId;
await this.pinMessage(messageId);
Expand Down
37 changes: 21 additions & 16 deletions src/api/ops/list.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,27 +2,32 @@ import { PathLike } from 'fs';

import { Client } from 'src/api';
import { FileOrDirectoryDoesNotExistError } from 'src/errors/path';
import { TGFSDirectory, TGFSFileRef } from 'src/model/directory';

import { navigateToDir } from './navigate-to-dir';
import { splitPath } from './utils';

export const list = (client: Client) => async (path: PathLike) => {
const [basePath, name] = splitPath(path);
const dir = await navigateToDir(client)(basePath);
export const list =
(client: Client) =>
async (
path: PathLike,
): Promise<TGFSFileRef | Array<TGFSFileRef | TGFSDirectory>> => {
const [basePath, name] = splitPath(path);
const dir = await navigateToDir(client)(basePath);

let nextDir = dir;
let nextDir = dir;

if (name) {
nextDir = dir.findChildren([name])[0];
}
if (nextDir) {
return [...nextDir.findChildren(), ...nextDir.findFiles()];
} else {
const nextFile = dir.findFiles([name])[0];
if (nextFile) {
return nextFile;
if (name) {
nextDir = dir.findChildren([name])[0];
}
if (nextDir) {
return [...nextDir.findChildren(), ...nextDir.findFiles()];
} else {
throw new FileOrDirectoryDoesNotExistError(path.toString());
const nextFile = dir.findFiles([name])[0];
if (nextFile) {
return nextFile;
} else {
throw new FileOrDirectoryDoesNotExistError(path.toString());
}
}
}
};
};
14 changes: 8 additions & 6 deletions src/api/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,16 @@ export type GetMessagesReq = Chat & {
messageIds: number[];
};

export type Document = {
size: BigInteger;
id: BigInteger;
accessHash: BigInteger;
fileReference: Buffer;
};

export type MessageResp = Message & {
text?: string;
document?: {
size: BigInteger;
id: BigInteger;
accessHash: BigInteger;
fileReference: Buffer;
};
document?: Document;
};

export type GetMessagesResp = MessageResp[];
Expand Down
34 changes: 15 additions & 19 deletions src/server/webdav/tgfs-filesystem.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,7 @@ import { Client, createClient } from 'src/api';
import { createDir, list, removeDir, removeFile } from 'src/api/ops';
import { createEmptyFile } from 'src/api/ops/create-empty-file';
import { uploadFromStream } from 'src/api/ops/upload';
import {
FileOrDirectoryAlreadyExistsError,
FileOrDirectoryDoesNotExistError,
InvalidNameError,
} from 'src/errors';
import { BusinessError } from 'src/errors/base';
import { TGFSDirectory, TGFSFileRef } from 'src/model/directory';
import { Logger } from 'src/utils/logger';

Expand All @@ -57,12 +53,13 @@ export class TGFSSerializer implements FileSystemSerializer {
}
}

const handleError = (callback: (e) => any) => (err) => {
if (err instanceof FileOrDirectoryAlreadyExistsError) {
const handleError = (callback: (e: Error) => any) => (err: Error) => {
const castedError = err as BusinessError;
if (castedError.code == 'FILE_OR_DIR_ALREADY_EXISTS') {
callback(Errors.ResourceAlreadyExists);
} else if (err instanceof FileOrDirectoryDoesNotExistError) {
} else if (castedError.code == 'FILE_OR_DIR_DOES_NOT_EXIST') {
callback(Errors.ResourceNotFound);
} else if (err instanceof InvalidNameError) {
} else if (castedError.code == 'INVALID_NAME') {
callback(Errors.IllegalArguments);
} else {
callback(Errors.InvalidOperation);
Expand Down Expand Up @@ -273,16 +270,15 @@ export class TGFSFileSystem extends FileSystem {
): void {
(async () => {
try {
const fileRef = await list(this.tgClient)(path.toString());
if (fileRef instanceof TGFSFileRef) {
const chunks = this.tgClient.downloadLatestVersion(
fileRef,
fileRef.name,
);
callback(null, Readable.from(chunks));
} else {
callback(Errors.InvalidOperation);
}
const fileRef = (await list(this.tgClient)(
path.toString(),
)) as TGFSFileRef;
const chunks = this.tgClient.downloadLatestVersion(
fileRef,
fileRef.name,
);

callback(null, Readable.from(chunks));
} catch (err) {
handleError(callback)(err);
Logger.error(err);
Expand Down
2 changes: 1 addition & 1 deletion src/utils/logger.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ export class Logger {
err.errors.forEach((e) => this.error(e));
} else if (err instanceof BusinessError) {
console.error(
`[${this.getTime()}] [ERROR] ${err.code} ${err.name} ${err.message}`,
`[${this.getTime()}] [ERROR] ${err.code} ${err.name} ${err.message} \n${err.stack}`,
);
} else if (err instanceof TechnicalError) {
console.error(
Expand Down
30 changes: 13 additions & 17 deletions test/api/model/operations.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,6 @@ describe('file and directory operations', () => {
});

describe('create / remove directories', () => {
var client: Client;

beforeEach(async () => {
client = await createMockClient();
});

it('should create a directory', async () => {
const client = await createMockClient();
const root = client.getRootDirectory();
Expand All @@ -31,10 +25,10 @@ describe('file and directory operations', () => {

await expect(
client.createDirectory({ name: '-d1', under: root }),
).rejects.toThrowError();
).rejects.toThrow();
await expect(
client.createDirectory({ name: 'd/1', under: root }),
).rejects.toThrowError();
).rejects.toThrow();
});

it('should remove a directory', async () => {
Expand All @@ -60,7 +54,7 @@ describe('file and directory operations', () => {
});

describe('create / remove files', () => {
var client: Client;
let client: Client;

beforeEach(async () => {
client = await createMockClient();
Expand All @@ -76,16 +70,17 @@ describe('file and directory operations', () => {
});

it('should create a small file from path', async () => {
fs.writeFileSync('./mock-file.txt', 'mock-file-content');
const fileName = `${Math.random()}.txt`;
fs.writeFileSync(fileName, 'mock-file-content');

const root = client.getRootDirectory();
const f1 = await client.uploadFile(
{ under: root },
{ name: 'f1', path: './mock-file.txt' },
{ name: 'f1', path: fileName },
);
expect(root.findFiles(['f1'])[0]).toEqual(f1);

fs.rmSync('./mock-file.txt');
fs.rmSync(fileName);
});

it('should create a big file from buffer', async () => {
Expand All @@ -101,18 +96,19 @@ describe('file and directory operations', () => {
});

it('should create a big file from path', async () => {
const fileName = `${Math.random()}.txt`;
const content = Buffer.alloc(1024 * 1024 * 10, 'a');
fs.writeFileSync('./mock-file.txt', content);
fs.writeFileSync(fileName, content);

const root = client.getRootDirectory();

const f1 = await client.uploadFile(
{ under: root },
{ name: 'f1', path: './mock-file.txt' },
{ name: 'f1', path: fileName },
);
expect(root.findFiles(['f1'])[0]).toEqual(f1);

fs.rmSync('./mock-file.txt');
fs.rmSync(fileName);
});

it('should add a file version', async () => {
Expand All @@ -122,7 +118,7 @@ describe('file and directory operations', () => {
{ name: 'f1', buffer: Buffer.from('mock-file-content') },
);

await sleep(300);
await sleep(300); // wait for the timestamp to change to ensure the order of versions
const content2 = 'mock-file-content-edited';
await client.uploadFile(
{ under: root },
Expand Down Expand Up @@ -224,7 +220,7 @@ describe('file and directory operations', () => {
);

const fr = root.findFiles(['f1'])[0];
const localFileName = 'test-download-file-content';
const localFileName = `${Math.random()}.txt`;

await saveToFile(client.downloadLatestVersion(fr, 'f1'), localFileName);

Expand Down
14 changes: 7 additions & 7 deletions test/cmd/cmd.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ describe('commands', () => {

it('should throw an error if path does not exist', () => {
jest.replaceProperty(process, 'argv', ['ls', '/not-exist']);
expect(executor.execute(parse())).rejects.toThrowError();
expect(executor.execute(parse())).rejects.toThrow();
});
});

Expand Down Expand Up @@ -100,12 +100,12 @@ describe('commands', () => {
await executor.execute(parse());

jest.replaceProperty(process, 'argv', ['mkdir', '/d1']);
await expect(executor.execute(parse())).rejects.toThrowError();
await expect(executor.execute(parse())).rejects.toThrow();
});

it('should throw an error if the path does not start with /', async () => {
jest.replaceProperty(process, 'argv', ['mkdir', 'd1']);
await expect(executor.execute(parse())).rejects.toThrowError();
await expect(executor.execute(parse())).rejects.toThrow();
});
});

Expand All @@ -114,8 +114,8 @@ describe('commands', () => {
await removeDir(client)('/', true);
});

it('should upload a file', async () => {
const fileName = 'mock-file.txt';
it('should upload a file from local', async () => {
const fileName = `${Math.random()}.txt`;

fs.writeFileSync(fileName, 'mock-file-content');
jest.replaceProperty(process, 'argv', ['cp', fileName, '/f1']);
Expand All @@ -124,12 +124,12 @@ describe('commands', () => {
const f1 = client.getRootDirectory().findFiles(['f1'])[0];
expect(f1.name).toEqual('f1');

fs.unlinkSync('./mock-file.txt');
fs.rmSync(fileName);
});

it('should throw an error if file does not exist', () => {
jest.replaceProperty(process, 'argv', ['cp', 'not-exist', '/f1']);
expect(executor.execute(parse())).rejects.toThrowError();
expect(executor.execute(parse())).rejects.toThrow();
});
});

Expand Down
Loading

0 comments on commit a948e0d

Please sign in to comment.