Skip to content

Commit

Permalink
Merge pull request #1565 from contentstack/test/dx-1203-test-cases-ra…
Browse files Browse the repository at this point in the history
…te-limit-command

dx | 1203 test cases rate limit command
  • Loading branch information
harshithad0703 authored Sep 13, 2024
2 parents 165d17f + 25dece3 commit caa5343
Show file tree
Hide file tree
Showing 5 changed files with 238 additions and 4 deletions.
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

0 comments on commit caa5343

Please sign in to comment.