Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

dx | 1203 test cases rate limit command #1565

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
28 changes: 28 additions & 0 deletions packages/contentstack-config/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ USAGE
* [`csdx config:set:base-branch`](#csdx-configsetbase-branch)
* [`csdx config:set:ea-header`](#csdx-configsetea-header)
* [`csdx config:set:early-access-header`](#csdx-configsetearly-access-header)
* [`csdx config:set:rate-limit`](#csdx-configsetrate-limit)
* [`csdx config:set:region [REGION]`](#csdx-configsetregion-region)

## `csdx config:get:base-branch`
Expand Down Expand Up @@ -298,6 +299,33 @@ EXAMPLES

_See code: [src/commands/config/set/early-access-header.ts](https://github.com/contentstack/cli/blob/main/packages/contentstack-config/src/commands/config/set/early-access-header.ts)_

## `csdx config:set:rate-limit`

Set rate-limit for CLI

```
USAGE
$ csdx config:set:rate-limit [--org <value>] [--utilize <value>] [--limit-name <value>] [--default]

FLAGS
--default Reset to default rate limit
--limit-name=<value>... [Optional] Provide the limit names separated by commas ['limit', 'getLimit', 'bulkLimit']
--org=<value> Provide the organization UID
--utilize=<value> [default: 50] Provide the utilization percentages for rate limit, separated by commas

DESCRIPTION
Set rate-limit for CLI

EXAMPLES
$ csdx config:set:rate-limit --org <<org_uid>>

$ csdx config:set:rate-limit --org <<org_uid>> --utilize 70,80 --limit-name getLimit,limit

$ csdx config:set:rate-limit --org <<org_uid>> --default
```

_See code: [src/commands/config/set/rate-limit.ts](https://github.com/contentstack/cli/blob/main/packages/contentstack-config/src/commands/config/set/rate-limit.ts)_

## `csdx config:set:region [REGION]`

Set region for CLI
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { askOrgID } from '../../../utils/interactive';
import { SetRateLimitConfig } from '../../../interfaces';
import { limitNamesConfig } from '../../../utils/common-utilities';

export default class RateLimitSetCommand extends BaseCommand<typeof RateLimitSetCommand> {
export default class SetRateLimitCommand extends BaseCommand<typeof SetRateLimitCommand> {
static description = 'Set rate-limit for CLI';

static flags: FlagInput = {
Expand Down Expand Up @@ -42,7 +42,7 @@ export default class RateLimitSetCommand extends BaseCommand<typeof RateLimitSet
this.exit(1);
}

const { flags } = await this.parse(RateLimitSetCommand);
const { flags } = await this.parse(SetRateLimitCommand);
let { org, utilize, 'limit-name': limitName } = flags;
const config: SetRateLimitConfig = { org: '', limitName: limitNamesConfig };

Expand All @@ -68,7 +68,7 @@ export default class RateLimitSetCommand extends BaseCommand<typeof RateLimitSet
if (limitName) {
const invalidLimitNames = limitName[0].split(',').map((name: string) => name.trim());

if (!limitNamesConfig.includes(invalidLimitNames)) {
if (invalidLimitNames.some((name: string) => !limitNamesConfig.includes(name))) {
cliux.error(`Invalid limit names provided: ${invalidLimitNames.join(', ')}`);
return;
} else {
Expand All @@ -79,7 +79,6 @@ export default class RateLimitSetCommand extends BaseCommand<typeof RateLimitSet
const limitHandler = new RateLimitHandler();
const managementAPIClient = await managementSDKClient(config);
limitHandler.setClient(managementAPIClient);
cliux.success(`Rate limit has been set successfully for org: ${config.org}`);
try {
await limitHandler.setRateLimit(config);
} catch (error) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ export class RateLimitHandler {

rateLimit[config.org] = limitsToUpdate;
configHandler.set('rateLimit', rateLimit);
cliux.success(`Rate limit has been set successfully for org: ${config.org}`);
} catch (error) {
cliux.error(`Error: Unable to set the rate limit`, error?.errorMessage || error?.message || error);
}
Expand Down
178 changes: 178 additions & 0 deletions packages/contentstack-config/test/unit/commands/rate-limit.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,178 @@
import { expect } from 'chai';
import { stub, restore } from 'sinon'; // Import restore for cleaning up
import { cliux, configHandler, isAuthenticated } from '@contentstack/cli-utilities';
import SetRateLimitCommand from '../../../src/commands/config/set/rate-limit';
import GetRateLimitCommand from '../../../src/commands/config/get/rate-limit';
import RemoveRateLimitCommand from '../../../src/commands/config/remove/rate-limit';
import { askOrgID } from '../../../src/utils/interactive';
import { RateLimitHandler } from '../../../src/utils/rate-limit-handler';
import { defaultRalteLimitConfig } from '../../../src/utils/common-utilities';

describe('Rate Limit Commands', () => {
let originalCliuxError: typeof cliux.error;
let originalCliuxPrint: typeof cliux.print;
let originalIsAuthenticated: () => boolean;
let errorMessage: any;
let printMessage: any;
let authenticated = isAuthenticated;
let rateLimitHandler: RateLimitHandler;
let mockClient: any;

beforeEach(() => {
originalCliuxError = cliux.error;
originalCliuxPrint = cliux.print;
originalIsAuthenticated = isAuthenticated;

cliux.error = (message: string) => {
errorMessage = message;
};
cliux.print = (message: string) => {
printMessage = message;
};
rateLimitHandler = new RateLimitHandler();
mockClient = {
organization: stub().returns({
fetch: stub().resolves({ plan: { features: [{ uid: 'getLimit' }, { uid: 'bulkLimit' }] } }),
}),
};
rateLimitHandler.setClient(mockClient);
restore();

restore();
});

afterEach(() => {
cliux.error = originalCliuxError;
cliux.print = originalCliuxPrint;
authenticated = originalIsAuthenticated;
});

describe('Set Rate Limit Command', () => {
it('Set Rate Limit: with all flags, should be successful', async () => {
const stub1 = stub(SetRateLimitCommand.prototype, 'run').resolves();
const args = ['--org', 'test-org-id', '--utilize', '70,80', '--limit-name', 'getLimit,bulkLimit'];
await SetRateLimitCommand.run(args);
expect(stub1.calledOnce).to.be.true;
});

it('Set Rate Limit: should handle invalid utilization percentages', async () => {
const args = ['--org', 'test-org-id', '--utilize', '150', '--limit-name', 'getLimit'];
await SetRateLimitCommand.run(args);
expect(errorMessage).to.equal('Utilize percentages must be numbers between 0 and 100.');
});

it('Set Rate Limit: should handle mismatch between utilize percentages and limit names', async () => {
const args = ['--org', 'test-org-id', '--utilize', '70', '--limit-name', 'getLimit,postLimit'];
await SetRateLimitCommand.run(args);
expect(errorMessage).to.equal(
'The number of utilization percentages must match the number of limit names provided.',
);
});

it('Set Rate Limit: should handle invalid number of limit names', async () => {
const args = ['--org', 'test-org-id', '--utilize', '70,80', '--limit-name', 'getLimit'];
await SetRateLimitCommand.run(args);
expect(errorMessage).to.equal(
'The number of utilization percentages must match the number of limit names provided.',
);
});

it('Set Rate Limit: should prompt for the organization UID', async () => {
const inquireStub = stub(cliux, 'inquire').resolves('test-org-id');
const orgID = await askOrgID();
expect(orgID).to.equal('test-org-id');
inquireStub.restore();
});

it('Set Rate Limit: should handle API client failure gracefully', async () => {
const handler = new RateLimitHandler();
handler.setClient({
organization: () => {
throw new Error('Client Error');
},
});
const config = { org: 'test-org-id', utilize: ['70'], 'limit-name': ['getLimit'] };
await handler.setRateLimit(config);
expect(errorMessage).to.include('Error: Unable to set the rate limit');
});

it('Set Rate Limit: should handle unauthenticated user', async () => {
const isAuthenticatedStub = stub().returns(false);
authenticated = isAuthenticatedStub;
const args = ['--org', 'test-org-id', '--utilize', '70,80', '--limit-name', 'getLimit,bulkLimit'];
try {
await SetRateLimitCommand.run(args);
} catch (error) {
expect(errorMessage).to.equal('You are not logged in. Please login with command $ csdx auth:login');
expect(error?.code).to.equal(1);
}
});
it('should set default rate limit for organization', async () => {
const config = { org: 'test-org-id', default: true };
await rateLimitHandler.setRateLimit(config);
const rateLimit = configHandler.get('rateLimit');
expect(rateLimit['test-org-id']).to.deep.equal(defaultRalteLimitConfig);
});

it('should set rate limit when only utilization percentages are provided', async () => {
const config = {
org: 'test-org-id',
utilize: ['70'],
'limit-name': ['getLimit'],
};
await rateLimitHandler.setRateLimit(config);
const rateLimit = configHandler.get('rateLimit');
expect(rateLimit['test-org-id']['getLimit'].utilize).to.equal(70);
});
});

describe('Get Rate Limit Command', () => {
const rateLimit = {
'test-org-id': {
getLimit: { value: 10, utilize: 70 },
bulkLimit: { value: 1, utilize: 80 },
},
};

it('Get Rate Limit: should print the rate limit for the given organization', async () => {
configHandler.set('rateLimit', rateLimit);
await GetRateLimitCommand.run(['--org', 'test-org-id']);
expect(printMessage).to.include(' test-org-id 10(70%) 0 1(80%) ');
});

it('Get Rate Limit: should throw an error if the organization is not found', async () => {
configHandler.set('rateLimit', {});
try {
await GetRateLimitCommand.run(['--org', 'non-existent-org']);
} catch (error) {
expect(errorMessage).to.equal('Error: Organization not found');
}
});
});

describe('Remove Rate Limit Command', () => {
const rateLimit = {
'test-org-id': {
getLimit: { value: 10, utilize: 70 },
bulkLimit: { value: 1, utilize: 80 },
},
};

it('Remove Rate Limit: should remove the rate limit for the given organization', async () => {
configHandler.set('rateLimit', rateLimit);
await RemoveRateLimitCommand.run(['--org', 'test-org-id']);
const updatedRateLimit = configHandler.get('rateLimit');
expect(updatedRateLimit['test-org-id']).to.be.undefined;
expect(printMessage).to.equal('Rate limit entry for organization UID test-org-id has been removed.');
});

it('Remove Rate Limit: should throw an error if the organization is not found', async () => {
configHandler.set('rateLimit', {});
try {
await RemoveRateLimitCommand.run(['--org', 'non-existent-org']);
} catch (error) {
expect(errorMessage).to.equal('Error: Organization not found');
}
});
});
});
28 changes: 28 additions & 0 deletions packages/contentstack/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ USAGE
* [`csdx config:set:base-branch`](#csdx-configsetbase-branch)
* [`csdx config:set:ea-header`](#csdx-configsetea-header)
* [`csdx config:set:early-access-header`](#csdx-configsetearly-access-header)
* [`csdx config:set:rate-limit`](#csdx-configsetrate-limit)
* [`csdx config:set:region [REGION]`](#csdx-configsetregion-region)
* [`csdx help [COMMANDS]`](#csdx-help-commands)
* [`csdx launch`](#csdx-launch)
Expand Down Expand Up @@ -3196,6 +3197,33 @@ EXAMPLES

_See code: [@contentstack/cli-config](https://github.com/contentstack/cli/blob/main/packages/contentstack-config/src/commands/config/set/early-access-header.ts)_

## `csdx config:set:rate-limit`

Set rate-limit for CLI

```
USAGE
$ csdx config:set:rate-limit [--org <value>] [--utilize <value>] [--limit-name <value>...] [--default]

FLAGS
--default Reset to default rate limit
--limit-name=<value>... [Optional] Provide the limit names separated by commas ['limit', 'getLimit', 'bulkLimit']
--org=<value> Provide the organization UID
--utilize=<value> [default: 50] Provide the utilization percentages for rate limit, separated by commas

DESCRIPTION
Set rate-limit for CLI

EXAMPLES
$ csdx config:set:rate-limit --org <<org_uid>>

$ csdx config:set:rate-limit --org <<org_uid>> --utilize 70,80 --limit-name getLimit,limit

$ csdx config:set:rate-limit --org <<org_uid>> --default
```

_See code: [@contentstack/cli-config](https://github.com/contentstack/cli/blob/main/packages/contentstack-config/src/commands/config/set/rate-limit.ts)_

## `csdx config:set:region [REGION]`

Set region for CLI
Expand Down
Loading