@@ -5,7 +5,7 @@ import { join } from "node:path";
55import { promisify } from "node:util" ;
66import { afterAll , beforeAll , beforeEach , describe , expect , it , vi } from "vitest" ;
77import yargs from "yargs" ;
8- import { register } from "../../src/commands/mapi/request.js" ;
8+ import { register as registerMapiCommand } from "../../src/commands/mapi/request.js" ;
99import type { MapiRequestParams } from "../../src/core/mapi/request.js" ;
1010import { performRawMapiRequest } from "../../src/core/mapi/request.js" ;
1111import { getValidAccessToken } from "../../src/lib/auth/tokenAccess.js" ;
@@ -31,7 +31,7 @@ type CommandRun = Readonly<{ failure: string | undefined; stdout: string; stderr
3131// Both streams are always captured: every 2xx writes somewhere, and a test that
3232// only cares about the parsed arguments must not spill that into the runner's output.
3333const runCommand = async ( argv : ReadonlyArray < string > ) : Promise < CommandRun > => {
34- const parser = register (
34+ const parser = registerMapiCommand (
3535 yargs ( [ ...argv ] )
3636 . strict ( )
3737 . exitProcess ( false )
@@ -94,13 +94,6 @@ describe("kontent mapi argument handling", () => {
9494 expect ( lastParams ( ) . headers ) . toContainEqual ( { name : "X-Foo" , value : "1" } ) ;
9595 } ) ;
9696
97- it ( "accepts -H after the endpoint too" , async ( ) => {
98- const { failure } = await runCommand ( [ "types" , "-H" , "X-Foo: 1" , "--envId" , ENV_ID ] ) ;
99-
100- expect ( failure ) . toBeUndefined ( ) ;
101- expect ( lastParams ( ) . endpoint ) . toBe ( "types" ) ;
102- } ) ;
103-
10497 it ( "collects a repeated -H into one header list" , async ( ) => {
10598 await runCommand ( [ "-H" , "X-Foo: 1" , "-H" , "X-Bar: 2" , "types" , "--envId" , ENV_ID ] ) ;
10699
@@ -165,6 +158,17 @@ describe("kontent mapi argument handling", () => {
165158 expect ( process . exitCode ) . toBe ( 1 ) ;
166159 } ) ;
167160
161+ it ( "reports a transport failure on stderr and fails" , async ( ) => {
162+ vi . mocked ( performRawMapiRequest ) . mockResolvedValueOnce (
163+ err ( { kind : "transport" , message : "fetch failed: getaddrinfo ENOTFOUND" } ) ,
164+ ) ;
165+ const { stdout, stderr } = await runCommand ( [ "types" , "--envId" , ENV_ID ] ) ;
166+
167+ expect ( stdout ) . toBe ( "" ) ;
168+ expect ( stderr ) . toContain ( "fetch failed: getaddrinfo ENOTFOUND" ) ;
169+ expect ( process . exitCode ) . toBe ( 1 ) ;
170+ } ) ;
171+
168172 it ( "sends the file at --input as the request body" , async ( ) => {
169173 const path = join ( tempDir , "body.json" ) ;
170174 await writeFile ( path , '{"name":"Article"}' ) ;
@@ -190,20 +194,24 @@ describe("kontent mapi argument handling", () => {
190194 expect ( await lastParams ( ) . body ?. text ( ) ) . toBe ( '{"name":"Article"}' ) ;
191195 } ) ;
192196
193- it . skipIf ( process . platform === "win32" ) (
194- "sends an empty body for a character device with nothing in it" ,
195- async ( ) => {
196- await runCommand ( [ "types" , "--input" , "/dev/null" , "--envId" , ENV_ID ] ) ;
197-
198- expect ( await lastParams ( ) . body ?. text ( ) ) . toBe ( "" ) ;
199- expect ( process . exitCode ) . toBeUndefined ( ) ;
200- } ,
201- ) ;
202-
203- it ( "wires no abort of its own, leaving SIGINT to the telemetry handler" , async ( ) => {
204- await runCommand ( [ "types" , "--envId" , ENV_ID ] ) ;
197+ // Without nargs on --input, strict mode rejects the lone "-" as an unknown positional.
198+ it ( "reads --input - from stdin, refusing when nothing is piped" , async ( ) => {
199+ // The runner's stdin is not a terminal, so the flag is set by hand and removed after.
200+ Object . defineProperty ( process . stdin , "isTTY" , { value : true , configurable : true } ) ;
201+ const { failure, stderr } = await runCommand ( [
202+ "types" ,
203+ "--input" ,
204+ "-" ,
205+ "--envId" ,
206+ ENV_ID ,
207+ ] ) . finally ( ( ) => {
208+ delete ( process . stdin as { isTTY ?: boolean } ) . isTTY ;
209+ } ) ;
205210
206- expect ( lastParams ( ) . abortSignal ) . toBeUndefined ( ) ;
211+ expect ( failure ) . toBeUndefined ( ) ;
212+ expect ( stderr ) . toContain ( "Nothing is piped to stdin" ) ;
213+ expect ( process . exitCode ) . toBe ( 1 ) ;
214+ expect ( performRawMapiRequest ) . not . toHaveBeenCalled ( ) ;
207215 } ) ;
208216
209217 it ( "reports an unreadable --input file without calling the API" , async ( ) => {
0 commit comments