mirror of
https://github.com/LukeHagar/vercel.git
synced 2025-12-10 12:57:47 +00:00
[cli] Allow ls to specify a limit up to 100 (#8735)
### Related Issues Allow the `ls` commands to have a `--limit` option that allows a user to fetch up to 100 records per page. Currently the default is 20, but the API allows up to 100. This keeps the default, if unspecified at 20. Fixes: https://linear.app/vercel/issue/VCCLI-244/add-limit-option-all-the-ls-subcommands This adds in `ls --limit` into: - [x] `alias ls` - [x] `certs ls` - [x] `dns ls` - [x] `domains ls` I note that `env` has an `ls` command, but it doesn't have a pagination command and [looking at the API](https://vercel.com/docs/rest-api#endpoints/projects/retrieve-the-environment-variables-of-a-project-by-id-or-name) it doesn't support pagination or limit. Wasn't sure if I should add in `-L` as a short cut to `--limit`, seems like a good idea. ~Couldn't find any tests that cover this API, but I could be looking in the wrong place, this is the first pull request, so my apologies if I've missed it. But I'll take another look tomorrow and leave it in the draft state for now.~ Added in unit tests for each of the commands and mocks for those unit tests, which is has caused this PR to get quite a bit larger, sorry about that. Of note for reviewers, there were a few places where I changed `console.log` to `output.log` to get the output passed to the tests - as far as I can tell everything works on the command line and in tests. ### 📋 Checklist #### Tests - [x] The code changed/added as part of this PR has been covered with tests - [x] All tests pass locally with `yarn test-unit` #### Code Review - [x] This PR has a concise title and thorough description useful to a reviewer - [x] Issue from task tracker has a link to this PR
This commit is contained in:
@@ -38,6 +38,9 @@ const help = () => {
|
||||
-S, --scope Set a custom scope
|
||||
-N, --next Show next page of results
|
||||
-y, --yes Skip the confirmation prompt when removing an alias
|
||||
--limit=${chalk.bold.underline(
|
||||
'VALUE'
|
||||
)} Number of results to return per page (default: 20, max: 100)
|
||||
|
||||
${chalk.dim('Examples:')}
|
||||
|
||||
@@ -81,6 +84,7 @@ export default async function main(client: Client) {
|
||||
'--json': Boolean,
|
||||
'--yes': Boolean,
|
||||
'--next': Number,
|
||||
'--limit': Number,
|
||||
'-y': '--yes',
|
||||
'-N': '--next',
|
||||
});
|
||||
|
||||
@@ -4,28 +4,30 @@ import table from 'text-table';
|
||||
import Client from '../../util/client';
|
||||
import getAliases from '../../util/alias/get-aliases';
|
||||
import getScope from '../../util/get-scope';
|
||||
import {
|
||||
PaginationOptions,
|
||||
getPaginationOpts,
|
||||
} from '../../util/get-pagination-opts';
|
||||
import stamp from '../../util/output/stamp';
|
||||
import strlen from '../../util/strlen';
|
||||
import getCommandFlags from '../../util/get-command-flags';
|
||||
import { getCommandName } from '../../util/pkg-name';
|
||||
|
||||
import { Alias } from '../../types';
|
||||
|
||||
interface Options {
|
||||
'--next'?: number;
|
||||
}
|
||||
|
||||
export default async function ls(
|
||||
client: Client,
|
||||
opts: Options,
|
||||
opts: PaginationOptions,
|
||||
args: string[]
|
||||
) {
|
||||
const { output } = client;
|
||||
const { '--next': nextTimestamp } = opts;
|
||||
const { contextName } = await getScope(client);
|
||||
|
||||
if (typeof nextTimestamp !== undefined && Number.isNaN(nextTimestamp)) {
|
||||
output.error('Please provide a number for flag --next');
|
||||
let paginationOptions;
|
||||
|
||||
try {
|
||||
paginationOptions = getPaginationOpts(opts);
|
||||
} catch (err: unknown) {
|
||||
output.prettyError(err);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -46,10 +48,10 @@ export default async function ls(
|
||||
const { aliases, pagination } = await getAliases(
|
||||
client,
|
||||
undefined,
|
||||
nextTimestamp
|
||||
...paginationOptions
|
||||
);
|
||||
output.log(`aliases found under ${chalk.bold(contextName)} ${lsStamp()}`);
|
||||
console.log(printAliasTable(aliases));
|
||||
output.log(printAliasTable(aliases));
|
||||
|
||||
if (pagination && pagination.count === 20) {
|
||||
const flags = getCommandFlags(opts, ['_', '--next']);
|
||||
|
||||
@@ -50,6 +50,9 @@ const help = () => {
|
||||
'FILE'
|
||||
)} CA certificate chain file
|
||||
-N, --next Show next page of results
|
||||
--limit=${chalk.bold.underline(
|
||||
'VALUE'
|
||||
)} Number of results to return per page (default: 20, max: 100)
|
||||
|
||||
${chalk.dim('Examples:')}
|
||||
|
||||
@@ -92,6 +95,7 @@ export default async function main(client: Client) {
|
||||
'--ca': String,
|
||||
'--next': Number,
|
||||
'-N': '--next',
|
||||
'--limit': Number,
|
||||
});
|
||||
} catch (err) {
|
||||
handleError(err);
|
||||
|
||||
@@ -3,6 +3,10 @@ import ms from 'ms';
|
||||
import table from 'text-table';
|
||||
import Client from '../../util/client';
|
||||
import getScope from '../../util/get-scope';
|
||||
import {
|
||||
PaginationOptions,
|
||||
getPaginationOpts,
|
||||
} from '../../util/get-pagination-opts';
|
||||
import stamp from '../../util/output/stamp';
|
||||
import getCerts from '../../util/certs/get-certs';
|
||||
import strlen from '../../util/strlen';
|
||||
@@ -10,23 +14,23 @@ import { Cert } from '../../types';
|
||||
import getCommandFlags from '../../util/get-command-flags';
|
||||
import { getCommandName } from '../../util/pkg-name';
|
||||
|
||||
interface Options {
|
||||
'--next'?: number;
|
||||
}
|
||||
|
||||
async function ls(
|
||||
client: Client,
|
||||
opts: Options,
|
||||
opts: PaginationOptions,
|
||||
args: string[]
|
||||
): Promise<number> {
|
||||
const { output } = client;
|
||||
const { '--next': nextTimestamp } = opts;
|
||||
const { contextName } = await getScope(client);
|
||||
|
||||
if (typeof nextTimestamp !== 'undefined' && Number.isNaN(nextTimestamp)) {
|
||||
output.error('Please provide a number for flag --next');
|
||||
let paginationOptions;
|
||||
|
||||
try {
|
||||
paginationOptions = getPaginationOpts(opts);
|
||||
} catch (err: unknown) {
|
||||
output.prettyError(err);
|
||||
return 1;
|
||||
}
|
||||
|
||||
const lsStamp = stamp();
|
||||
|
||||
if (args.length !== 0) {
|
||||
@@ -39,9 +43,10 @@ async function ls(
|
||||
}
|
||||
|
||||
// Get the list of certificates
|
||||
const { certs, pagination } = await getCerts(client, nextTimestamp).catch(
|
||||
err => err
|
||||
);
|
||||
const { certs, pagination } = await getCerts(
|
||||
client,
|
||||
...paginationOptions
|
||||
).catch(err => err);
|
||||
|
||||
output.log(
|
||||
`${
|
||||
@@ -50,7 +55,7 @@ async function ls(
|
||||
);
|
||||
|
||||
if (certs.length > 0) {
|
||||
console.log(formatCertsTable(certs));
|
||||
output.log(formatCertsTable(certs));
|
||||
}
|
||||
|
||||
if (pagination && pagination.count === 20) {
|
||||
|
||||
@@ -38,6 +38,9 @@ const help = () => {
|
||||
)} Login token
|
||||
-S, --scope Set a custom scope
|
||||
-N, --next Show next page of results
|
||||
--limit=${chalk.bold.underline(
|
||||
'VALUE'
|
||||
)} Number of results to return per page (default: 20, max: 100)
|
||||
|
||||
${chalk.dim('Examples:')}
|
||||
|
||||
@@ -100,7 +103,11 @@ export default async function main(client: Client) {
|
||||
let argv;
|
||||
|
||||
try {
|
||||
argv = getArgs(client.argv.slice(2), { '--next': Number, '-N': '--next' });
|
||||
argv = getArgs(client.argv.slice(2), {
|
||||
'--next': Number,
|
||||
'-N': '--next',
|
||||
'--limit': Number,
|
||||
});
|
||||
} catch (error) {
|
||||
handleError(error);
|
||||
return 1;
|
||||
|
||||
@@ -9,21 +9,20 @@ import getDNSRecords, {
|
||||
} from '../../util/dns/get-dns-records';
|
||||
import getDomainDNSRecords from '../../util/dns/get-domain-dns-records';
|
||||
import getScope from '../../util/get-scope';
|
||||
import {
|
||||
PaginationOptions,
|
||||
getPaginationOpts,
|
||||
} from '../../util/get-pagination-opts';
|
||||
import stamp from '../../util/output/stamp';
|
||||
import getCommandFlags from '../../util/get-command-flags';
|
||||
import { getCommandName } from '../../util/pkg-name';
|
||||
|
||||
type Options = {
|
||||
'--next'?: number;
|
||||
};
|
||||
|
||||
export default async function ls(
|
||||
client: Client,
|
||||
opts: Options,
|
||||
opts: PaginationOptions,
|
||||
args: string[]
|
||||
) {
|
||||
const { output } = client;
|
||||
const { '--next': nextTimestamp } = opts;
|
||||
const { contextName } = await getScope(client);
|
||||
|
||||
const [domainName] = args;
|
||||
@@ -38,8 +37,12 @@ export default async function ls(
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (typeof nextTimestamp !== 'undefined' && Number.isNaN(nextTimestamp)) {
|
||||
output.error('Please provide a number for flag --next');
|
||||
let paginationOptions;
|
||||
|
||||
try {
|
||||
paginationOptions = getPaginationOpts(opts);
|
||||
} catch (err: unknown) {
|
||||
output.prettyError(err);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -48,8 +51,8 @@ export default async function ls(
|
||||
output,
|
||||
client,
|
||||
domainName,
|
||||
nextTimestamp,
|
||||
4
|
||||
4,
|
||||
...paginationOptions
|
||||
);
|
||||
if (data instanceof DomainNotFound) {
|
||||
output.error(
|
||||
@@ -67,7 +70,7 @@ export default async function ls(
|
||||
records.length > 0 ? 'Records' : 'No records'
|
||||
} found under ${chalk.bold(contextName)} ${chalk.gray(lsStamp())}`
|
||||
);
|
||||
console.log(getDNSRecordsTable([{ domainName, records }]));
|
||||
output.log(getDNSRecordsTable([{ domainName, records }]));
|
||||
|
||||
if (pagination && pagination.count === 20) {
|
||||
const flags = getCommandFlags(opts, ['_', '--next']);
|
||||
@@ -85,7 +88,7 @@ export default async function ls(
|
||||
output,
|
||||
client,
|
||||
contextName,
|
||||
nextTimestamp
|
||||
...paginationOptions
|
||||
);
|
||||
const nRecords = dnsRecords.reduce((p, r) => r.records.length + p, 0);
|
||||
output.log(
|
||||
@@ -93,7 +96,7 @@ export default async function ls(
|
||||
contextName
|
||||
)} ${chalk.gray(lsStamp())}`
|
||||
);
|
||||
console.log(getDNSRecordsTable(dnsRecords));
|
||||
output.log(getDNSRecordsTable(dnsRecords));
|
||||
if (pagination && pagination.count === 20) {
|
||||
const flags = getCommandFlags(opts, ['_', '--next']);
|
||||
output.log(
|
||||
|
||||
@@ -45,6 +45,9 @@ const help = () => {
|
||||
)} Login token
|
||||
-S, --scope Set a custom scope
|
||||
-N, --next Show next page of results
|
||||
--limit=${chalk.bold.underline(
|
||||
'VALUE'
|
||||
)} Number of results to return per page (default: 20, max: 100)
|
||||
-y, --yes Skip the confirmation prompt when removing a domain
|
||||
|
||||
${chalk.dim('Examples:')}
|
||||
@@ -94,6 +97,7 @@ export default async function main(client: Client) {
|
||||
'--next': Number,
|
||||
'-N': '--next',
|
||||
'-y': '--yes',
|
||||
'--limit': Number,
|
||||
});
|
||||
} catch (error) {
|
||||
handleError(error);
|
||||
|
||||
@@ -10,24 +10,27 @@ import formatTable from '../../util/format-table';
|
||||
import { formatDateWithoutTime } from '../../util/format-date';
|
||||
import { Domain } from '../../types';
|
||||
import getCommandFlags from '../../util/get-command-flags';
|
||||
import {
|
||||
PaginationOptions,
|
||||
getPaginationOpts,
|
||||
} from '../../util/get-pagination-opts';
|
||||
import { getCommandName } from '../../util/pkg-name';
|
||||
import isDomainExternal from '../../util/domains/is-domain-external';
|
||||
import { getDomainRegistrar } from '../../util/domains/get-domain-registrar';
|
||||
|
||||
type Options = {
|
||||
'--next': number;
|
||||
};
|
||||
|
||||
export default async function ls(
|
||||
client: Client,
|
||||
opts: Partial<Options>,
|
||||
opts: Partial<PaginationOptions>,
|
||||
args: string[]
|
||||
) {
|
||||
const { output } = client;
|
||||
const { '--next': nextTimestamp } = opts;
|
||||
|
||||
if (typeof nextTimestamp !== undefined && Number.isNaN(nextTimestamp)) {
|
||||
output.error('Please provide a number for flag --next');
|
||||
let paginationOptions;
|
||||
|
||||
try {
|
||||
paginationOptions = getPaginationOpts(opts);
|
||||
} catch (err: unknown) {
|
||||
output.prettyError(err);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -46,7 +49,10 @@ export default async function ls(
|
||||
|
||||
output.spinner(`Fetching Domains under ${chalk.bold(contextName)}`);
|
||||
|
||||
const { domains, pagination } = await getDomains(client, nextTimestamp);
|
||||
const { domains, pagination } = await getDomains(
|
||||
client,
|
||||
...paginationOptions
|
||||
);
|
||||
|
||||
output.log(
|
||||
`${plural('Domain', domains.length, true)} found under ${chalk.bold(
|
||||
|
||||
@@ -9,12 +9,14 @@ type Response = {
|
||||
export default async function getAliases(
|
||||
client: Client,
|
||||
deploymentId?: string,
|
||||
next?: number
|
||||
next?: number,
|
||||
limit = 20
|
||||
) {
|
||||
let aliasUrl = `/v3/now/aliases?limit=20`;
|
||||
let aliasUrl = `/v3/now/aliases?limit=${limit}`;
|
||||
if (next) {
|
||||
aliasUrl += `&until=${next}`;
|
||||
}
|
||||
|
||||
const to = deploymentId
|
||||
? `/now/deployments/${deploymentId}/aliases`
|
||||
: aliasUrl;
|
||||
|
||||
@@ -6,8 +6,12 @@ type Response = {
|
||||
pagination: PaginationOptions;
|
||||
};
|
||||
|
||||
export default async function getCerts(client: Client, next?: number) {
|
||||
let certsUrl = `/v4/now/certs?limit=20`;
|
||||
export default async function getCerts(
|
||||
client: Client,
|
||||
next?: number,
|
||||
limit = 20
|
||||
) {
|
||||
let certsUrl = `/v4/now/certs?limit=${limit}`;
|
||||
|
||||
if (next) {
|
||||
certsUrl += `&until=${next}`;
|
||||
|
||||
@@ -12,14 +12,15 @@ export default async function getDomainDNSRecords(
|
||||
output: Output,
|
||||
client: Client,
|
||||
domain: string,
|
||||
apiVersion = 3,
|
||||
nextTimestamp?: number,
|
||||
apiVersion = 3
|
||||
limit = 20
|
||||
) {
|
||||
output.debug(`Fetching for DNS records of domain ${domain}`);
|
||||
try {
|
||||
let url = `/v${apiVersion}/domains/${encodeURIComponent(
|
||||
domain
|
||||
)}/records?limit=20`;
|
||||
)}/records?limit=${limit}`;
|
||||
|
||||
if (nextTimestamp) {
|
||||
url += `&until=${nextTimestamp}`;
|
||||
|
||||
@@ -6,8 +6,12 @@ type Response = {
|
||||
pagination: PaginationOptions;
|
||||
};
|
||||
|
||||
export default async function getDomains(client: Client, next?: number) {
|
||||
let domainUrl = `/v5/domains?limit=20`;
|
||||
export default async function getDomains(
|
||||
client: Client,
|
||||
next?: number,
|
||||
limit = 20
|
||||
) {
|
||||
let domainUrl = `/v5/domains?limit=${limit}`;
|
||||
if (next) {
|
||||
domainUrl += `&until=${next}`;
|
||||
}
|
||||
|
||||
21
packages/cli/src/util/get-pagination-opts.ts
Normal file
21
packages/cli/src/util/get-pagination-opts.ts
Normal file
@@ -0,0 +1,21 @@
|
||||
export interface PaginationOptions {
|
||||
'--next'?: number;
|
||||
'--limit'?: number;
|
||||
}
|
||||
|
||||
export function getPaginationOpts(opts: PaginationOptions) {
|
||||
const { '--next': nextTimestamp, '--limit': limit } = opts;
|
||||
|
||||
if (typeof nextTimestamp !== undefined && Number.isNaN(nextTimestamp)) {
|
||||
throw new Error('Please provide a number for option --next');
|
||||
}
|
||||
|
||||
if (
|
||||
typeof limit === 'number' &&
|
||||
(!Number.isInteger(limit) || limit > 100 || limit < 1)
|
||||
) {
|
||||
throw new Error('Please provide an integer from 1 to 100 for option --limit');
|
||||
}
|
||||
|
||||
return [nextTimestamp, limit];
|
||||
}
|
||||
32
packages/cli/test/mocks/alias.ts
Normal file
32
packages/cli/test/mocks/alias.ts
Normal file
@@ -0,0 +1,32 @@
|
||||
import chance from 'chance';
|
||||
import { client } from './client';
|
||||
|
||||
export function useAlias() {
|
||||
function create(alias: string) {
|
||||
return {
|
||||
alias: `dummy-${alias}.app`,
|
||||
created: chance().timestamp(),
|
||||
createdAt: chance().timestamp(),
|
||||
deletedAt: null,
|
||||
deployment: {
|
||||
id: chance().guid(),
|
||||
url: chance().domain(),
|
||||
},
|
||||
deploymentId: chance().guid(),
|
||||
projectId: chance().guid(),
|
||||
redirect: null,
|
||||
redirectStatusCode: null,
|
||||
uid: chance().guid(),
|
||||
updatedAt: chance().timestamp(),
|
||||
};
|
||||
}
|
||||
|
||||
client.scenario.get('/v3/now/aliases', (_req, res) => {
|
||||
const limit = parseInt(_req.query.limit);
|
||||
const aliases = Array.from({ length: limit }, (v, i) => create(`${i}`));
|
||||
res.json({
|
||||
aliases: aliases,
|
||||
pagination: { count: limit, total: limit, page: 1, pages: 1 },
|
||||
});
|
||||
});
|
||||
}
|
||||
24
packages/cli/test/mocks/certs.ts
Normal file
24
packages/cli/test/mocks/certs.ts
Normal file
@@ -0,0 +1,24 @@
|
||||
import chance from 'chance';
|
||||
import { client } from './client';
|
||||
|
||||
export function useCert() {
|
||||
function create(cert: string) {
|
||||
return {
|
||||
uid: `dummy-${cert}.cert`,
|
||||
created: chance().timestamp(),
|
||||
expiration: chance().timestamp(),
|
||||
renew: chance().bool(),
|
||||
cns: [chance().domain()],
|
||||
age: chance().integer({ min: 0, max: 1000 }),
|
||||
};
|
||||
}
|
||||
|
||||
client.scenario.get('/v4/now/certs', (_req, res) => {
|
||||
const limit = parseInt(_req.query.limit);
|
||||
const certs = Array.from({ length: limit }, (v, i) => create(`${i}`));
|
||||
res.json({
|
||||
certs: certs,
|
||||
pagination: { count: limit, total: limit, page: 1, pages: 1 },
|
||||
});
|
||||
});
|
||||
}
|
||||
31
packages/cli/test/mocks/dns.ts
Normal file
31
packages/cli/test/mocks/dns.ts
Normal file
@@ -0,0 +1,31 @@
|
||||
import chance from 'chance';
|
||||
import { client } from './client';
|
||||
import { createDomain } from './domains';
|
||||
|
||||
export function useDns() {
|
||||
client.scenario.get('/v3/domains/:domain?/records', (_req, res) => {
|
||||
res.json({
|
||||
records: [
|
||||
{
|
||||
id: chance().guid(),
|
||||
name: chance().domain(),
|
||||
type: chance().string(),
|
||||
value: chance().integer(),
|
||||
createdAt: chance().timestamp(),
|
||||
},
|
||||
],
|
||||
pagination: { count: 1, total: 1, page: 1, pages: 1 },
|
||||
});
|
||||
});
|
||||
|
||||
client.scenario.get('/v5/domains', (req, res) => {
|
||||
const limit = parseInt(req.query.limit);
|
||||
const domains = Array.from({ length: limit }, (_, k) =>
|
||||
createDomain(k.toString())
|
||||
);
|
||||
res.json({
|
||||
domains: domains,
|
||||
pagination: { count: limit, total: limit, page: 1, pages: 1 },
|
||||
});
|
||||
});
|
||||
}
|
||||
42
packages/cli/test/mocks/domains.ts
Normal file
42
packages/cli/test/mocks/domains.ts
Normal file
@@ -0,0 +1,42 @@
|
||||
import chance from 'chance';
|
||||
import { client } from './client';
|
||||
|
||||
export function createDomain(k: string) {
|
||||
return {
|
||||
suffix: chance().bool(),
|
||||
verified: chance().bool(),
|
||||
nameservers: chance().string(),
|
||||
intendedNameservers: chance().string(),
|
||||
customNameservers: chance().string(),
|
||||
creator: {
|
||||
username: chance().string(),
|
||||
email: chance().email(),
|
||||
customerId: chance().guid(),
|
||||
isDomainReseller: chance().bool(),
|
||||
id: chance().guid(),
|
||||
},
|
||||
createdAt: chance().timestamp(),
|
||||
id: chance().guid(),
|
||||
name: k ? `example-${k}.com` : 'example.com',
|
||||
expiresAt: chance().timestamp(),
|
||||
boughtAt: chance().timestamp(),
|
||||
orderedAt: chance().timestamp(),
|
||||
renew: chance().bool(),
|
||||
serviceType: chance().string(),
|
||||
transferredAt: chance().timestamp(),
|
||||
transferStartedAt: chance().timestamp(),
|
||||
};
|
||||
}
|
||||
|
||||
export function useDomains() {
|
||||
client.scenario.get('/v5/domains', (req, res) => {
|
||||
const limit = parseInt(req.query.limit);
|
||||
const domains = Array.from({ length: limit }, (v, i) =>
|
||||
createDomain(`${i}`)
|
||||
);
|
||||
res.json({
|
||||
domains: domains,
|
||||
pagination: { count: limit, total: limit, page: 1, pages: 1 },
|
||||
});
|
||||
});
|
||||
}
|
||||
24
packages/cli/test/unit/commands/alias.test.ts
Normal file
24
packages/cli/test/unit/commands/alias.test.ts
Normal file
@@ -0,0 +1,24 @@
|
||||
import { client } from '../../mocks/client';
|
||||
import alias from '../../../src/commands/alias';
|
||||
import { useUser } from '../../mocks/user';
|
||||
import { useAlias } from '../../mocks/alias';
|
||||
|
||||
describe('alias', () => {
|
||||
it('should list up to 20 aliases by default', async () => {
|
||||
useUser();
|
||||
useAlias();
|
||||
client.setArgv('alias', 'ls');
|
||||
const exitCodePromise = alias(client);
|
||||
await expect(exitCodePromise).resolves.toEqual(0);
|
||||
await expect(client.stderr).toOutput('dummy-19.app');
|
||||
});
|
||||
|
||||
it('should list up to 2 aliases', async () => {
|
||||
useUser();
|
||||
useAlias();
|
||||
client.setArgv('alias', 'ls', '--limit', '2');
|
||||
const exitCodePromise = alias(client);
|
||||
await expect(exitCodePromise).resolves.toEqual(0);
|
||||
await expect(client.stderr).toOutput('dummy-1.app');
|
||||
});
|
||||
});
|
||||
24
packages/cli/test/unit/commands/certs.test.ts
Normal file
24
packages/cli/test/unit/commands/certs.test.ts
Normal file
@@ -0,0 +1,24 @@
|
||||
import { client } from '../../mocks/client';
|
||||
import certs from '../../../src/commands/certs';
|
||||
import { useUser } from '../../mocks/user';
|
||||
import { useCert } from '../../mocks/certs';
|
||||
|
||||
describe('certs', () => {
|
||||
it('should list up to 20 certs by default', async () => {
|
||||
useUser();
|
||||
useCert();
|
||||
client.setArgv('certs', 'ls');
|
||||
const exitCodePromise = certs(client);
|
||||
await expect(client.stderr).toOutput('dummy-19.cert');
|
||||
await expect(exitCodePromise).resolves.toEqual(0);
|
||||
});
|
||||
|
||||
it('should list up to 2 certs if limit set to 2', async () => {
|
||||
useUser();
|
||||
useCert();
|
||||
client.setArgv('certs', 'ls', '--limit', '2');
|
||||
const exitCodePromise = certs(client);
|
||||
await expect(client.stderr).toOutput('dummy-1.cert');
|
||||
await expect(exitCodePromise).resolves.toEqual(0);
|
||||
});
|
||||
});
|
||||
24
packages/cli/test/unit/commands/dns.test.ts
Normal file
24
packages/cli/test/unit/commands/dns.test.ts
Normal file
@@ -0,0 +1,24 @@
|
||||
import { client } from '../../mocks/client';
|
||||
import dns from '../../../src/commands/dns';
|
||||
import { useUser } from '../../mocks/user';
|
||||
import { useDns } from '../../mocks/dns';
|
||||
|
||||
describe('dns', () => {
|
||||
it('should list up to 20 dns by default', async () => {
|
||||
useUser();
|
||||
useDns();
|
||||
client.setArgv('dns', 'ls');
|
||||
let exitCodePromise = dns(client);
|
||||
await expect(client.stderr).toOutput('example-19.com');
|
||||
await expect(exitCodePromise).resolves.toEqual(0);
|
||||
});
|
||||
|
||||
it('should list up to 2 dns if limit set to 2', async () => {
|
||||
useUser();
|
||||
useDns();
|
||||
client.setArgv('dns', 'ls', '--limit', 2);
|
||||
let exitCodePromise = dns(client);
|
||||
await expect(client.stderr).toOutput('example-2.com');
|
||||
await expect(exitCodePromise).resolves.toEqual(0);
|
||||
});
|
||||
});
|
||||
24
packages/cli/test/unit/commands/domains.test.ts
Normal file
24
packages/cli/test/unit/commands/domains.test.ts
Normal file
@@ -0,0 +1,24 @@
|
||||
import { client } from '../../mocks/client';
|
||||
import domains from '../../../src/commands/domains';
|
||||
import { useUser } from '../../mocks/user';
|
||||
import { useDomains } from '../../mocks/domains';
|
||||
|
||||
describe('domains', () => {
|
||||
it('should list up to 20 domains by default', async () => {
|
||||
useUser();
|
||||
useDomains();
|
||||
client.setArgv('domains', 'ls');
|
||||
let exitCodePromise = domains(client);
|
||||
await expect(client.stderr).toOutput('example-19.com');
|
||||
await expect(exitCodePromise).resolves.toEqual(0);
|
||||
});
|
||||
|
||||
it('should list up to 2 domains if limit set to 2', async () => {
|
||||
useUser();
|
||||
useDomains();
|
||||
client.setArgv('domains', 'ls', '--limit', '2');
|
||||
const exitCodePromise = domains(client);
|
||||
await expect(client.stderr).toOutput('example-1.com');
|
||||
await expect(exitCodePromise).resolves.toEqual(0);
|
||||
});
|
||||
});
|
||||
20
packages/cli/test/unit/util/get-pagination-opts.test.ts
Normal file
20
packages/cli/test/unit/util/get-pagination-opts.test.ts
Normal file
@@ -0,0 +1,20 @@
|
||||
import { getPaginationOpts } from '../../../src/util/get-pagination-opts';
|
||||
import getArgs from '../../../src/util/get-args';
|
||||
|
||||
describe('getOpts', () => {
|
||||
it('should throw an error if next not a number', async () => {
|
||||
const args = getArgs([`--next=oops`], { '--next': Number });
|
||||
expect(() => {
|
||||
getPaginationOpts(args);
|
||||
}).toThrowError();
|
||||
});
|
||||
|
||||
it('should throw an error if limit not valid', async () => {
|
||||
for (let limit of ['abc', '101', '1.1', '-1']) {
|
||||
const args = getArgs([`--limit=${limit}`], { '--limit': Number });
|
||||
expect(() => {
|
||||
getPaginationOpts(args);
|
||||
}).toThrowError();
|
||||
}
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user