Skip to content
Closed
Show file tree
Hide file tree
Changes from 5 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
97 changes: 97 additions & 0 deletions src/app/drive/services/limit.service.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
import { describe, it, expect, vi, beforeEach } from 'vitest';
import limitService from './limit.service';
import { SdkFactory } from '../../core/factory/sdk';
import { HUNDRED_TB } from 'app/core/components/Sidenav/Sidenav';

vi.mock('@internxt/sdk', () => ({
Network: {},
}));

vi.mock('app/store', () => ({
default: {
dispatch: vi.fn(),
getState: vi.fn(),
},
}));

vi.mock('app/store/slices/session', () => ({
sessionActions: {
resetState: vi.fn(),
},
}));

vi.mock('../../core/factory/sdk', () => ({
SdkFactory: {
getNewApiInstance: vi.fn(),
},
}));

vi.mock('./size.service', () => {
const bytesToStringMock = (size) => {
return size > 0 ? 'formatted-size' : '';
};

return {
bytesToString: bytesToStringMock,
default: {
bytesToString: bytesToStringMock,
},
};
});

describe('limitService', () => {
const mockStorageClient = {
spaceLimitV2: vi.fn(),
};

beforeEach(() => {
vi.clearAllMocks();

vi.spyOn(SdkFactory, 'getNewApiInstance').mockReturnValue({
createNewStorageClient: vi.fn().mockReturnValue(mockStorageClient),
} as any);
});

describe('fetchLimit', () => {
it('should fetch space limit successfully', async () => {
const maxSpaceBytes = 1024 * 1024 * 1024 * 10; // 10GB
mockStorageClient.spaceLimitV2.mockResolvedValue({ maxSpaceBytes });

const result = await limitService.fetchLimit();

expect(SdkFactory.getNewApiInstance).toHaveBeenCalled();
expect(mockStorageClient.spaceLimitV2).toHaveBeenCalled();
expect(result).toEqual(maxSpaceBytes);
});

it('should handle errors when fetching space limit', async () => {
const error = new Error('Failed to fetch space limit');
mockStorageClient.spaceLimitV2.mockRejectedValue(error);

await expect(limitService.fetchLimit()).rejects.toThrow(error);
});
});

describe('formatLimit', () => {
it('should return ellipsis for zero or negative limit values', () => {
expect(limitService.formatLimit(0)).toBe('...');
expect(limitService.formatLimit(-100)).toBe('...');
});

it('should return infinity symbol for limits greater than 100TB', () => {
const largeLimit = HUNDRED_TB + 1024;
const result = limitService.formatLimit(largeLimit);
expect(result).toBe('\u221E');
});

it('should format positive values less than 100TB', () => {
const smallLimit = 1024 * 1024 * 50; // 50MB
const result = limitService.formatLimit(smallLimit);

expect(result).not.toBe('...');
expect(result).not.toBe('\u221E');
expect(typeof result).toBe('string');
expect(result.length).toBeGreaterThan(0);
});
});
});
4 changes: 2 additions & 2 deletions src/app/drive/services/limit.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ import { SdkFactory } from '../../core/factory/sdk';
import { HUNDRED_TB } from 'app/core/components/Sidenav/Sidenav';

async function fetchLimit(): Promise<number> {
const storageClient = SdkFactory.getInstance().createStorageClient();
return storageClient.spaceLimit().then((response) => {
const storageClient = SdkFactory.getNewApiInstance().createNewStorageClient();
return storageClient.spaceLimitV2().then((response) => {
return response.maxSpaceBytes;
});
}
Expand Down
117 changes: 117 additions & 0 deletions src/app/drive/services/usage.service.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
import { describe, it, expect, vi, beforeEach } from 'vitest';
import usageService from './usage.service';
import { SdkFactory } from '../../core/factory/sdk';
import errorService from '../../core/services/error.service';

vi.mock('../../core/factory/sdk', () => ({
SdkFactory: {
getNewApiInstance: vi.fn(),
},
}));

vi.mock('../../core/services/error.service', () => ({
default: {
reportError: vi.fn(),
},
}));

describe('usageService', () => {
const mockStorageClient = {
spaceUsageV2: vi.fn(),
};

beforeEach(() => {
vi.clearAllMocks();

vi.spyOn(SdkFactory, 'getNewApiInstance').mockReturnValue({
createNewStorageClient: vi.fn().mockReturnValue(mockStorageClient),
} as any);
});

describe('fetchUsage', () => {
it('should fetch usage successfully', async () => {
const usageResponse = {
drive: 1024 * 1024 * 100, // 100MB
backups: 1024 * 1024 * 50, // 50MB
photos: 0,
total: 1024 * 1024 * 150, // 150MB
};
mockStorageClient.spaceUsageV2.mockResolvedValue(usageResponse);

const result = await usageService.fetchUsage();

expect(SdkFactory.getNewApiInstance).toHaveBeenCalled();
expect(mockStorageClient.spaceUsageV2).toHaveBeenCalled();
expect(result).toEqual(usageResponse);
});

it('should handle errors when fetching usage', async () => {
const error = new Error('Failed to fetch usage');
mockStorageClient.spaceUsageV2.mockRejectedValue(error);

await expect(usageService.fetchUsage()).rejects.toThrow(error);
});
});

describe('getUsageDetails', () => {
it('should get usage details successfully', async () => {
const usageResponse = {
drive: 1024 * 1024 * 100, // 100MB
backups: 1024 * 1024 * 50, // 50MB
};
mockStorageClient.spaceUsageV2.mockResolvedValue(usageResponse);

const result = await usageService.getUsageDetails();

expect(SdkFactory.getNewApiInstance).toHaveBeenCalled();
expect(mockStorageClient.spaceUsageV2).toHaveBeenCalled();
expect(result).toEqual({
drive: usageResponse.drive,
photos: 0,
backups: usageResponse.backups,
});
});

it('should handle errors and report them', async () => {
const error = new Error('Failed to fetch usage details');
mockStorageClient.spaceUsageV2.mockRejectedValue(error);

const result = await usageService.getUsageDetails();

expect(errorService.reportError).toHaveBeenCalledWith(error);
expect(result).toEqual({ drive: 0, photos: 0, backups: 0 });
});
});

describe('getUsagePercent', () => {
it('should calculate usage percentage correctly', () => {
const usage = 250;
const limit = 1000;
const expectedPercent = 25;

const result = usageService.getUsagePercent(usage, limit);

expect(result).toBe(expectedPercent);
});

it('should round up percentage to nearest integer', () => {
const usage = 101;
const limit = 1000;
const expectedPercent = 11;

const result = usageService.getUsagePercent(usage, limit);

expect(result).toBe(expectedPercent);
});

it('should handle 100% usage correctly', () => {
const usage = 1000;
const limit = 1000;
const expectedPercent = 100;

const result = usageService.getUsagePercent(usage, limit);

expect(result).toBe(expectedPercent);
});
});
});
12 changes: 6 additions & 6 deletions src/app/drive/services/usage.service.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { UsageResponse } from '@internxt/sdk/dist/drive/storage/types';
import { UsageResponseV2 } from '@internxt/sdk/dist/drive/storage/types';
import { SdkFactory } from '../../core/factory/sdk';
import errorService from '../../core/services/error.service';

Expand All @@ -8,21 +8,21 @@ export interface UsageDetailsProps {
backups: number;
}

export async function fetchUsage(): Promise<UsageResponse> {
const storageClient = SdkFactory.getInstance().createStorageClient();
const driveUsage = await storageClient.spaceUsage();
export async function fetchUsage(): Promise<UsageResponseV2> {
const storageClient = SdkFactory.getNewApiInstance().createNewStorageClient();
const driveUsage = await storageClient.spaceUsageV2();

return driveUsage;
}

async function getUsageDetails(): Promise<UsageDetailsProps> {
const storageClient = SdkFactory.getInstance().createStorageClient();
const storageClient = SdkFactory.getNewApiInstance().createNewStorageClient();

let drive = 0;
let backups = 0;

try {
const { drive: storageDrive, backups: storageBackups } = await storageClient.spaceUsage();
const { drive: storageDrive, backups: storageBackups } = await storageClient.spaceUsageV2();
drive = storageDrive;
backups = storageBackups;
} catch (error) {
Expand Down
4 changes: 2 additions & 2 deletions src/app/newSettings/Sections/Account/Plans/utils/planUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import {
StoragePlan,
UserSubscription,
} from '@internxt/sdk/dist/drive/payments/types/types';
import { UsageResponse } from '@internxt/sdk/dist/drive/storage/types';
import { UsageResponse, UsageResponseV2 } from '@internxt/sdk/dist/drive/storage/types';
import { bytesToString } from 'app/drive/services/size.service';
import { t } from 'i18next';
import { FreeStoragePlan } from '../../../../../drive/types';
Expand Down Expand Up @@ -86,7 +86,7 @@ const getPlanName = (storagePlan: StoragePlan | null, limit?: number) => {
if (limit) return bytesToString(limit, false);
return FreeStoragePlan.simpleName;
};
const getCurrentUsage = (usage: UsageResponse | null) => {
const getCurrentUsage = (usage: UsageResponse | UsageResponseV2 | null) => {
return usage?.total ?? -1;
};

Expand Down
6 changes: 3 additions & 3 deletions src/app/store/slices/plan/index.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { createAsyncThunk, createSlice, PayloadAction } from '@reduxjs/toolkit';

import { StoragePlan, UserSubscription, UserType } from '@internxt/sdk/dist/drive/payments/types/types';
import { UsageResponse } from '@internxt/sdk/dist/drive/storage/types';
import { UsageResponse, UsageResponseV2 } from '@internxt/sdk/dist/drive/storage/types';
import { GetMemberUsageResponse } from '@internxt/sdk/dist/workspaces';
import workspacesService from 'app/core/services/workspace.service';
import limitService from 'app/drive/services/limit.service';
Expand All @@ -20,7 +20,7 @@ export interface PlanState {
teamPlan: StoragePlan | null;
planLimit: number;
planUsage: number;
usageDetails: UsageResponse | null;
usageDetails: UsageResponseV2 | null;
individualSubscription: UserSubscription | null;
businessSubscription: UserSubscription | null;
businessPlanLimit: number;
Expand Down Expand Up @@ -77,7 +77,7 @@ export const fetchLimitThunk = createAsyncThunk<number, void, { state: RootState
},
);

export const fetchUsageThunk = createAsyncThunk<UsageResponse | null, void, { state: RootState }>(
export const fetchUsageThunk = createAsyncThunk<UsageResponseV2 | null, void, { state: RootState }>(
'plan/fetchUsage',
async (payload: void, { getState }) => {
const isAuthenticated = getState().user.isAuthenticated;
Expand Down
Loading