diff --git a/generator/src/main/resources/line-bot-sdk-nodejs-generator/apiBody/multipart.pebble b/generator/src/main/resources/line-bot-sdk-nodejs-generator/apiBody/multipart.pebble index a36b0251d..f1bfe6c7a 100644 --- a/generator/src/main/resources/line-bot-sdk-nodejs-generator/apiBody/multipart.pebble +++ b/generator/src/main/resources/line-bot-sdk-nodejs-generator/apiBody/multipart.pebble @@ -8,11 +8,17 @@ {% endif -%} const form = new FormData(); {% for param in op.formParams -%} - {% if param.isFile -%} - form.append("{{param.paramName}}", {{param.paramName}}); // file - {% else -%} - form.append("{{param.paramName}}", String({{param.paramName}})); - {% endif -%} +{% if not param.required -%} + if ({{ param.paramName }} !== undefined) { +{% endif -%} +{% if param.isFile -%} + form.append("{{ param.baseName }}", {{ param.paramName }}); // file +{% else -%} + form.append("{{ param.baseName }}", String({{ param.paramName }})); +{% endif -%} +{% if not param.required -%} + } +{% endif -%} {% endfor %} const res = await this.httpClient.{{op.httpMethod|lower}}{% if op.hasFormParams %}Form{% endif %}Multipart( {% if op.pathParams|length > 0 %}requestPath{% else %}"{{ op.path }}"{% endif %}, diff --git a/lib/manage-audience/api/manageAudienceBlobClient.ts b/lib/manage-audience/api/manageAudienceBlobClient.ts index 6f5355020..20db329db 100644 --- a/lib/manage-audience/api/manageAudienceBlobClient.ts +++ b/lib/manage-audience/api/manageAudienceBlobClient.ts @@ -114,8 +114,12 @@ export class ManageAudienceBlobClient { uploadDescription?: string, ): Promise> { const form = new FormData(); - form.append("audienceGroupId", String(audienceGroupId)); - form.append("uploadDescription", String(uploadDescription)); + if (audienceGroupId !== undefined) { + form.append("audienceGroupId", String(audienceGroupId)); + } + if (uploadDescription !== undefined) { + form.append("uploadDescription", String(uploadDescription)); + } form.append("file", file); // file const res = await this.httpClient.putFormMultipart( @@ -171,9 +175,15 @@ export class ManageAudienceBlobClient { uploadDescription?: string, ): Promise> { const form = new FormData(); - form.append("description", String(description)); - form.append("isIfaAudience", String(isIfaAudience)); - form.append("uploadDescription", String(uploadDescription)); + if (description !== undefined) { + form.append("description", String(description)); + } + if (isIfaAudience !== undefined) { + form.append("isIfaAudience", String(isIfaAudience)); + } + if (uploadDescription !== undefined) { + form.append("uploadDescription", String(uploadDescription)); + } form.append("file", file); // file const res = await this.httpClient.postFormMultipart( diff --git a/test/libs-manageAudience.spec.ts b/test/libs-manageAudience.spec.ts index 29046230e..e13193b61 100644 --- a/test/libs-manageAudience.spec.ts +++ b/test/libs-manageAudience.spec.ts @@ -1,7 +1,7 @@ import { manageAudience } from "../lib/index.js"; import { http, HttpResponse } from "msw"; import { setupServer } from "msw/node"; -import { deepEqual, equal, match } from "node:assert"; +import { deepEqual, equal, match, ok, strictEqual } from "node:assert"; import { describe, it, beforeAll, afterAll, afterEach } from "vitest"; @@ -129,4 +129,74 @@ describe("manageAudience", () => { equal(requestCount, 1); deepEqual(res.body, {}); }); + + it("createAudienceForUploadingUserIds omits undefined optional fields", async () => { + let received: FormData | null = null; + server.use( + http.post( + "https://api-data.line.me/v2/bot/audienceGroup/upload/byFile", + async ({ request }) => { + received = await request.formData(); + return HttpResponse.json({}); + }, + ), + ); + + const file = new Blob(["user-id-1"], { type: "text/plain" }); + await blobClient.createAudienceForUploadingUserIds(file); + + const form: FormData = received!; + ok(form); + ok(form.get("file") instanceof File); + strictEqual(form.has("description"), false); + strictEqual(form.has("isIfaAudience"), false); + strictEqual(form.has("uploadDescription"), false); + }); + + it("addUserIdsToAudience omits undefined optional fields", async () => { + let received: FormData | null = null; + server.use( + http.put( + "https://api-data.line.me/v2/bot/audienceGroup/upload/byFile", + async ({ request }) => { + received = await request.formData(); + return HttpResponse.json({}); + }, + ), + ); + + const file = new Blob(["user-id-1"], { type: "text/plain" }); + await blobClient.addUserIdsToAudience(file); + + const form: FormData = received!; + ok(form); + ok(form.get("file") instanceof File); + strictEqual(form.has("audienceGroupId"), false); + strictEqual(form.has("uploadDescription"), false); + }); + + it("createAudienceForUploadingUserIds preserves false for isIfaAudience", async () => { + let received: FormData | null = null; + server.use( + http.post( + "https://api-data.line.me/v2/bot/audienceGroup/upload/byFile", + async ({ request }) => { + received = await request.formData(); + return HttpResponse.json({}); + }, + ), + ); + + const file = new Blob(["user-id-1"], { type: "text/plain" }); + await blobClient.createAudienceForUploadingUserIds( + file, + "test_description", + false, + ); + + const form: FormData = received!; + ok(form); + strictEqual(form.get("isIfaAudience"), "false"); + strictEqual(form.get("description"), "test_description"); + }); });