diff --git a/docs/cli/sandbox.md b/docs/cli/sandbox.md index e7a7ced0f..555249943 100644 --- a/docs/cli/sandbox.md +++ b/docs/cli/sandbox.md @@ -119,12 +119,14 @@ b2c sandbox list --json ### Output ``` -Realm Instance State Profile Created EOL +Realm Instance State Profile Created EOL ────────────────────────────────────────────────────────────────────────── -abcd 001 started medium 12/20/2024, 10:00 AM 12/21/2024, 10:00 AM -abcd 002 stopped large 12/19/2024, 2:30 PM 12/20/2024, 2:30 PM +abcd 001 started medium 2024-12-20 2024-12-21 +abcd 002 stopped large 2024-12-19 2024-12-20 22:30 ``` +The `EOL` column displays `YYYY-MM-DD` normally. When a sandbox expires within 24 hours (or is already expired), the time is also shown as `YYYY-MM-DD HH:mm` (UTC). + --- ## b2c sandbox create diff --git a/packages/b2c-cli/src/commands/sandbox/list.ts b/packages/b2c-cli/src/commands/sandbox/list.ts index 80f163824..4a2de9ef9 100644 --- a/packages/b2c-cli/src/commands/sandbox/list.ts +++ b/packages/b2c-cli/src/commands/sandbox/list.ts @@ -18,7 +18,7 @@ interface OdsListResponse { data: SandboxModel[]; } -const COLUMNS: Record> = { +export const COLUMNS: Record> = { realm: { header: 'Realm', get: (s) => s.realm || '-', @@ -41,7 +41,18 @@ const COLUMNS: Record> = { }, eol: { header: 'EOL', - get: (s) => (s.eol ? new Date(s.eol).toISOString().slice(0, 10) : '-'), + get(s) { + if (!s.eol) return '-'; + const d = new Date(s.eol); + const date = d.toISOString().slice(0, 10); + const msUntilEol = d.getTime() - Date.now(); + if (msUntilEol <= 24 * 60 * 60 * 1000) { + const hh = String(d.getUTCHours()).padStart(2, '0'); + const mm = String(d.getUTCMinutes()).padStart(2, '0'); + return `${date} ${hh}:${mm}`; + } + return date; + }, }, id: { header: 'ID', diff --git a/packages/b2c-cli/test/commands/sandbox/list.test.ts b/packages/b2c-cli/test/commands/sandbox/list.test.ts index aa360c5fd..ba88b52b3 100644 --- a/packages/b2c-cli/test/commands/sandbox/list.test.ts +++ b/packages/b2c-cli/test/commands/sandbox/list.test.ts @@ -6,7 +6,7 @@ import {expect} from 'chai'; import sinon from 'sinon'; -import SandboxList from '../../../src/commands/sandbox/list.js'; +import SandboxList, {COLUMNS} from '../../../src/commands/sandbox/list.js'; import {isolateConfig, restoreConfig} from '@salesforce/b2c-tooling-sdk/test-utils'; import {runSilent} from '../../helpers/test-setup.js'; @@ -97,6 +97,44 @@ describe('sandbox list', () => { }); }); + describe('eol column formatting', () => { + const getEol = COLUMNS.eol.get; + + it('returns "-" when eol is missing', () => { + expect(getEol({} as any)).to.equal('-'); + }); + + it('returns YYYY-MM-DD when EOL is more than 24 hours away', () => { + const future = new Date(Date.now() + 48 * 60 * 60 * 1000).toISOString(); + const result = getEol({eol: future} as any); + expect(result).to.match(/^\d{4}-\d{2}-\d{2}$/); + }); + + it('returns YYYY-MM-DD HH:mm when EOL is within 24 hours', () => { + const soon = new Date(Date.now() + 2 * 60 * 60 * 1000).toISOString(); + const result = getEol({eol: soon} as any); + expect(result).to.match(/^\d{4}-\d{2}-\d{2} \d{2}:\d{2}$/); + }); + + it('returns YYYY-MM-DD HH:mm for an already-expired EOL', () => { + const past = new Date(Date.now() - 60 * 60 * 1000).toISOString(); + const result = getEol({eol: past} as any); + expect(result).to.match(/^\d{4}-\d{2}-\d{2} \d{2}:\d{2}$/); + }); + + it('returns correct UTC time in YYYY-MM-DD HH:mm format', () => { + // Fixed timestamp: 2026-02-20T09:30:00Z — within 24h from now in the test + const eolTime = new Date(Date.now() + 30 * 60 * 1000).toISOString(); // 30 minutes away + const d = new Date(eolTime); + const expectedDate = d.toISOString().slice(0, 10); + const expectedHH = String(d.getUTCHours()).padStart(2, '0'); + const expectedMM = String(d.getUTCMinutes()).padStart(2, '0'); + + const result = getEol({eol: eolTime} as any); + expect(result).to.equal(`${expectedDate} ${expectedHH}:${expectedMM}`); + }); + }); + describe('filter parameter building', () => { it('should build filter params from realm flag', () => { const command = new SandboxList([], {} as any);