From fdf4ce8b6098488b35728d7602199fd5acf4d73a Mon Sep 17 00:00:00 2001 From: Greg Methvin Date: Tue, 24 Mar 2026 11:54:17 -0700 Subject: [PATCH] Use params schemas for all methods --- src/client/catalogs.ts | 26 +++++++++++-------- src/client/lists.ts | 5 ++-- src/client/templates.ts | 9 ++++--- src/client/users.ts | 28 ++++++++++++--------- src/types/catalogs.ts | 10 ++++++++ src/types/users.ts | 12 +++++++++ tests/integration/campaigns.test.ts | 4 +-- tests/integration/catalogs.test.ts | 20 +++++++-------- tests/integration/general.test.ts | 2 +- tests/integration/lists.test.ts | 6 ++--- tests/integration/subscriptions.test.ts | 2 +- tests/integration/templates.test.ts | 20 +++++++-------- tests/integration/users.test.ts | 12 ++++----- tests/unit/catalogs.test.ts | 33 ++++++++++++++++++------- tests/unit/templates.test.ts | 2 +- tests/unit/users.test.ts | 16 ++++++------ tests/utils/test-helpers.ts | 4 +-- 17 files changed, 129 insertions(+), 82 deletions(-) diff --git a/src/client/catalogs.ts b/src/client/catalogs.ts index 1f3c0ab..cb224a2 100644 --- a/src/client/catalogs.ts +++ b/src/client/catalogs.ts @@ -4,7 +4,11 @@ import { CatalogFieldMappingsResponseSchema, CatalogItemWithProperties, CatalogItemWithPropertiesSchema, + CreateCatalogParams, + DeleteCatalogItemParams, + DeleteCatalogParams, GetCatalogFieldMappingsParams, + GetCatalogItemParams, GetCatalogItemsParams, GetCatalogItemsResponse, GetCatalogItemsResponseSchema, @@ -28,9 +32,11 @@ import type { BaseIterableClient } from "./base.js"; */ export function Catalogs>(Base: T) { return class extends Base { - async createCatalog(catalogName: string): Promise { + async createCatalog( + params: CreateCatalogParams + ): Promise { const response = await this.client.post( - `/api/catalogs/${encodeURIComponent(catalogName)}` + `/api/catalogs/${encodeURIComponent(params.catalogName)}` ); return this.validateResponse(response, IterableSuccessResponseSchema); } @@ -63,21 +69,19 @@ export function Catalogs>(Base: T) { } async getCatalogItem( - catalogName: string, - itemId: string + params: GetCatalogItemParams ): Promise { const response = await this.client.get( - `/api/catalogs/${encodeURIComponent(catalogName)}/items/${encodeURIComponent(itemId)}` + `/api/catalogs/${encodeURIComponent(params.catalogName)}/items/${encodeURIComponent(params.itemId)}` ); return this.validateResponse(response, CatalogItemWithPropertiesSchema); } async deleteCatalogItem( - catalogName: string, - itemId: string + params: DeleteCatalogItemParams ): Promise { const response = await this.client.delete( - `/api/catalogs/${encodeURIComponent(catalogName)}/items/${encodeURIComponent(itemId)}` + `/api/catalogs/${encodeURIComponent(params.catalogName)}/items/${encodeURIComponent(params.itemId)}` ); return this.validateResponse(response, IterableSuccessResponseSchema); } @@ -168,9 +172,11 @@ export function Catalogs>(Base: T) { /** * Delete a catalog */ - async deleteCatalog(catalogName: string): Promise { + async deleteCatalog( + params: DeleteCatalogParams + ): Promise { const response = await this.client.delete( - `/api/catalogs/${encodeURIComponent(catalogName)}` + `/api/catalogs/${encodeURIComponent(params.catalogName)}` ); return this.validateResponse(response, IterableSuccessResponseSchema); } diff --git a/src/client/lists.ts b/src/client/lists.ts index ad7d2d8..d2db20a 100644 --- a/src/client/lists.ts +++ b/src/client/lists.ts @@ -6,6 +6,7 @@ import { CreateListParams, CreateListResponse, CreateListResponseSchema, + DeleteListParams, GetListPreviewUsersParams, GetListPreviewUsersResponse, GetListPreviewUsersResponseSchema, @@ -91,8 +92,8 @@ export function Lists>(Base: T) { return this.validateResponse(response, CreateListResponseSchema); } - async deleteList(listId: number): Promise { - const response = await this.client.delete(`/api/lists/${listId}`); + async deleteList(params: DeleteListParams): Promise { + const response = await this.client.delete(`/api/lists/${params.listId}`); return this.validateResponse(response, IterableSuccessResponseSchema); } diff --git a/src/client/templates.ts b/src/client/templates.ts index 4c75e46..586ab90 100644 --- a/src/client/templates.ts +++ b/src/client/templates.ts @@ -11,6 +11,7 @@ import { BulkDeleteTemplatesResponseSchema, EmailTemplate, EmailTemplateSchema, + GetTemplateByClientIdParams, GetTemplateByClientIdResponse, GetTemplateByClientIdResponseSchema, GetTemplateParams, @@ -145,12 +146,12 @@ export function Templates>(Base: T) { } async getTemplateByClientId( - clientTemplateId: string + params: GetTemplateByClientIdParams ): Promise { const response = await this.client.get( "/api/templates/getByClientTemplateId", { - params: { clientTemplateId }, + params: { clientTemplateId: params.clientTemplateId }, } ); return this.validateResponse( @@ -174,9 +175,9 @@ export function Templates>(Base: T) { * @deprecated Use {@link bulkDeleteTemplates} instead */ async deleteTemplates( - templateIds: number[] + params: BulkDeleteTemplatesParams ): Promise { - return this.bulkDeleteTemplates({ ids: templateIds }); + return this.bulkDeleteTemplates(params); } // Email Template Management diff --git a/src/client/users.ts b/src/client/users.ts index 1bdde74..e443db2 100644 --- a/src/client/users.ts +++ b/src/client/users.ts @@ -8,9 +8,13 @@ import { } from "../types/lists.js"; import { BulkUpdateUsersParams, + DeleteUserByEmailParams, + DeleteUserByUserIdParams, GetSentMessagesParams, GetSentMessagesResponse, GetSentMessagesResponseSchema, + GetUserByEmailParams, + GetUserByIdParams, GetUserFieldsResponse, GetUserFieldsResponseSchema, UpdateEmailParams, @@ -30,12 +34,10 @@ export function Users>(Base: T) { * Get a user by email address */ async getUserByEmail( - email: string, - opts?: { signal?: AbortSignal } + params: GetUserByEmailParams ): Promise { const response = await this.client.get( - `/api/users/${encodeURIComponent(email)}`, - opts?.signal ? { signal: opts.signal } : {} + `/api/users/${encodeURIComponent(params.email)}` ); return this.validateResponse(response, UserResponseSchema); } @@ -44,12 +46,10 @@ export function Users>(Base: T) { * Get a user by userId */ async getUserByUserId( - userId: string, - opts?: { signal?: AbortSignal } + params: GetUserByIdParams ): Promise { const response = await this.client.get( - `/api/users/byUserId/${encodeURIComponent(userId)}`, - opts?.signal ? { signal: opts.signal } : {} + `/api/users/byUserId/${encodeURIComponent(params.userId)}` ); return this.validateResponse(response, UserResponseSchema); } @@ -69,9 +69,11 @@ export function Users>(Base: T) { * Delete a user by email address * Asynchronous operation - does not prevent future data collection */ - async deleteUserByEmail(email: string): Promise { + async deleteUserByEmail( + params: DeleteUserByEmailParams + ): Promise { const response = await this.client.delete( - `/api/users/${encodeURIComponent(email)}` + `/api/users/${encodeURIComponent(params.email)}` ); return this.validateResponse(response, IterableSuccessResponseSchema); } @@ -81,9 +83,11 @@ export function Users>(Base: T) { * Asynchronous operation - does not prevent future data collection * If multiple users share the same userId, they'll all be deleted */ - async deleteUserByUserId(userId: string): Promise { + async deleteUserByUserId( + params: DeleteUserByUserIdParams + ): Promise { const response = await this.client.delete( - `/api/users/byUserId/${encodeURIComponent(userId)}` + `/api/users/byUserId/${encodeURIComponent(params.userId)}` ); return this.validateResponse(response, IterableSuccessResponseSchema); } diff --git a/src/types/catalogs.ts b/src/types/catalogs.ts index 7ad37af..ebe9caf 100644 --- a/src/types/catalogs.ts +++ b/src/types/catalogs.ts @@ -109,6 +109,16 @@ export type GetCatalogFieldMappingsParams = z.infer< >; export type CreateCatalogParams = z.infer; +export const DeleteCatalogParamsSchema = z.object({ + catalogName: z + .string() + .max(255) + .regex(/^[a-zA-Z0-9-]+$/) + .describe("Name of the catalog to delete"), +}); + +export type DeleteCatalogParams = z.infer; + // Catalog items schemas export const CatalogItemWithPropertiesSchema = z.object({ catalogName: z.string(), diff --git a/src/types/users.ts b/src/types/users.ts index 59eea6f..f568f9e 100644 --- a/src/types/users.ts +++ b/src/types/users.ts @@ -35,6 +35,8 @@ export const GetUserByEmailParamsSchema = z.object({ email: z.email().describe("Email address of the user to retrieve"), }); +export type GetUserByEmailParams = z.infer; + export const UpdateUserParamsSchema = z .object({ email: z.email().optional().describe("User email address"), @@ -69,6 +71,8 @@ export const GetUserByIdParamsSchema = z.object({ userId: z.string().describe("User ID to retrieve"), }); +export type GetUserByIdParams = z.infer; + export const BulkUpdateUsersParamsSchema = z.object({ users: z .array( @@ -95,10 +99,18 @@ export const DeleteUserByEmailParamsSchema = z.object({ email: z.email().describe("Email address of the user to delete"), }); +export type DeleteUserByEmailParams = z.infer< + typeof DeleteUserByEmailParamsSchema +>; + export const DeleteUserByUserIdParamsSchema = z.object({ userId: z.string().describe("User ID of the user to delete"), }); +export type DeleteUserByUserIdParams = z.infer< + typeof DeleteUserByUserIdParamsSchema +>; + export const UserEventsResponseSchema = z.object({ events: z.array(z.record(z.string(), z.any())), }); diff --git a/tests/integration/campaigns.test.ts b/tests/integration/campaigns.test.ts index 69fafce..e914106 100644 --- a/tests/integration/campaigns.test.ts +++ b/tests/integration/campaigns.test.ts @@ -161,7 +161,7 @@ describe("Campaign Management Integration Tests", () => { if (createdTestList) { try { - await withTimeout(client.deleteList(testListId)); + await withTimeout(client.deleteList({ listId: testListId })); } catch (error) { console.warn(`Failed to delete test list ${testListId}:`, error); } @@ -169,7 +169,7 @@ describe("Campaign Management Integration Tests", () => { if (createdTestTemplate) { try { - await withTimeout(client.deleteTemplates([testTemplateId])); + await withTimeout(client.deleteTemplates({ ids: [testTemplateId] })); } catch (error) { console.warn(`Failed to delete test template ${testTemplateId}:`, error); } diff --git a/tests/integration/catalogs.test.ts b/tests/integration/catalogs.test.ts index b83b340..e2cb923 100644 --- a/tests/integration/catalogs.test.ts +++ b/tests/integration/catalogs.test.ts @@ -25,7 +25,7 @@ describe("Catalog Management Integration Tests", () => { it("get nonexistent catalog item should 404", async () => { await expect( - client.getCatalogItem("nonexistent-catalog", "nonexistent-item") + client.getCatalogItem({ catalogName: "nonexistent-catalog", itemId: "nonexistent-item" }) ).rejects.toMatchObject({ statusCode: 404, }); @@ -42,7 +42,7 @@ describe("Catalog Management Integration Tests", () => { it("should get catalog field mappings with correct structure", async () => { // Create a test catalog const catalogName = uniqueId("test-catalog-mappings"); - await withTimeout(client.createCatalog(catalogName)); + await withTimeout(client.createCatalog({ catalogName })); // Add some items to the catalog with various field types await withTimeout( @@ -77,7 +77,7 @@ describe("Catalog Management Integration Tests", () => { it("should get catalog items", async () => { // Always create a fresh test catalog to ensure clean test state const catalogName = uniqueId("test-catalog-items"); - await withTimeout(client.createCatalog(catalogName)); + await withTimeout(client.createCatalog({ catalogName })); const itemId1 = uniqueId("catalog-items-test-1"); const itemId2 = uniqueId("catalog-items-test-2"); @@ -128,7 +128,7 @@ describe("Catalog Management Integration Tests", () => { it("should handle pagination parameters for catalog items", async () => { // Always create a fresh test catalog for pagination testing const catalogName = uniqueId("test-catalog-pagination"); - await withTimeout(client.createCatalog(catalogName)); + await withTimeout(client.createCatalog({ catalogName })); const itemId1 = uniqueId("pagination-test-1"); const itemId2 = uniqueId("pagination-test-2"); @@ -196,10 +196,10 @@ describe("Catalog Management Integration Tests", () => { it("should delete a catalog", async () => { // Create a test catalog to delete const catalogName = uniqueId("test-catalog-delete"); - await withTimeout(client.createCatalog(catalogName)); + await withTimeout(client.createCatalog({ catalogName })); // Delete the catalog - const result = await withTimeout(client.deleteCatalog(catalogName)); + const result = await withTimeout(client.deleteCatalog({ catalogName })); expect(result).toBeDefined(); expect(result).toHaveProperty("msg"); @@ -212,7 +212,7 @@ describe("Catalog Management Integration Tests", () => { it("should update catalog field mappings", async () => { // Create a test catalog const catalogName = uniqueId("test-catalog-field-mappings"); - await withTimeout(client.createCatalog(catalogName)); + await withTimeout(client.createCatalog({ catalogName })); // Add items with some fields first await withTimeout( @@ -258,7 +258,7 @@ describe("Catalog Management Integration Tests", () => { it("should bulk delete catalog items", async () => { // Create a test catalog const catalogName = uniqueId("test-catalog-bulk-delete"); - await withTimeout(client.createCatalog(catalogName)); + await withTimeout(client.createCatalog({ catalogName })); const itemId1 = uniqueId("bulk-delete-1"); const itemId2 = uniqueId("bulk-delete-2"); @@ -296,7 +296,7 @@ describe("Catalog Management Integration Tests", () => { it("should partial update a catalog item", async () => { // Create a test catalog const catalogName = uniqueId("test-catalog-patch"); - await withTimeout(client.createCatalog(catalogName)); + await withTimeout(client.createCatalog({ catalogName })); const itemId = uniqueId("patch-item"); @@ -345,7 +345,7 @@ describe("Catalog Management Integration Tests", () => { it("should replace a catalog item", async () => { // Create a test catalog const catalogName = uniqueId("test-catalog-replace"); - await withTimeout(client.createCatalog(catalogName)); + await withTimeout(client.createCatalog({ catalogName })); const itemId = uniqueId("replace-item"); diff --git a/tests/integration/general.test.ts b/tests/integration/general.test.ts index 66b0d3c..43d862d 100644 --- a/tests/integration/general.test.ts +++ b/tests/integration/general.test.ts @@ -53,7 +53,7 @@ describe("General Integration Tests", () => { // For non-existent users, Iterable API returns an empty object const userResponse = await withTimeout( - client.getUserByEmail(nonExistentEmail) + client.getUserByEmail({ email: nonExistentEmail }) ); expect(userResponse).toEqual({}); diff --git a/tests/integration/lists.test.ts b/tests/integration/lists.test.ts index 892086d..050f030 100644 --- a/tests/integration/lists.test.ts +++ b/tests/integration/lists.test.ts @@ -94,7 +94,7 @@ describe("List Management Integration Tests", () => { await waitForListMembership(client, listId, testUserEmail, false); } finally { // Cleanup - delete the list (success indicated by no exception) - await withTimeout(client.deleteList(listId)); + await withTimeout(client.deleteList({ listId })); } }, 120000); @@ -145,7 +145,7 @@ describe("List Management Integration Tests", () => { } finally { // Clean up test list if (testListId!) { - await withTimeout(client.deleteList(testListId)); + await withTimeout(client.deleteList({ listId: testListId })); } } }, 120000); @@ -199,7 +199,7 @@ describe("List Management Integration Tests", () => { } finally { // Clean up test list if (testListId!) { - await withTimeout(client.deleteList(testListId)); + await withTimeout(client.deleteList({ listId: testListId })); } } }, 120000); diff --git a/tests/integration/subscriptions.test.ts b/tests/integration/subscriptions.test.ts index 2c5118a..4cf4027 100644 --- a/tests/integration/subscriptions.test.ts +++ b/tests/integration/subscriptions.test.ts @@ -60,7 +60,7 @@ describe("Subscription Management Integration Tests", () => { // Clean up test list only if we created it if (createdTestList) { try { - await withTimeout(client.deleteList(testListId)); + await withTimeout(client.deleteList({ listId: testListId })); } catch (error) { console.warn(`Failed to delete test list ${testListId}:`, error); } diff --git a/tests/integration/templates.test.ts b/tests/integration/templates.test.ts index 2d2ab4f..80c87ff 100644 --- a/tests/integration/templates.test.ts +++ b/tests/integration/templates.test.ts @@ -173,14 +173,14 @@ describe("Template Management Integration Tests", () => { templateId = extractTemplateId(createResponse as { msg: string }); const retrievedTemplateResponse = await withTimeout( - client.getTemplateByClientId(clientTemplateId) + client.getTemplateByClientId({ clientTemplateId }) ); expect(retrievedTemplateResponse.templates.length).toBeGreaterThan(0); const retrievedTemplate = retrievedTemplateResponse.templates[0]!; expect(retrievedTemplate.templateId).toBe(templateId); } finally { if (templateId) { - await withTimeout(client.deleteTemplates([templateId])); + await withTimeout(client.deleteTemplates({ ids: [templateId] })); } } }); @@ -285,14 +285,14 @@ describe("Template Management Integration Tests", () => { expect(updatedTemplate.name).toBe(updateParams.name); const deleteResponse = await withTimeout( - client.deleteTemplates([templateId]) + client.deleteTemplates({ ids: [templateId] }) ); expect(deleteResponse.success).toContain(templateId); templateId = undefined; } finally { if (templateId) { try { - await withTimeout(client.deleteTemplates([templateId])); + await withTimeout(client.deleteTemplates({ ids: [templateId] })); } catch (cleanupError) { logger.warn( `Failed to cleanup ${type} template ${templateId}:`, @@ -334,12 +334,12 @@ describe("Template Management Integration Tests", () => { expect(result.msg).toContain("Sent proof to"); expect(result.msg).toContain(testUserEmail); - await withTimeout(client.deleteTemplates([templateId])); + await withTimeout(client.deleteTemplates({ ids: [templateId] })); templateId = undefined; } catch (error) { if (templateId) { try { - await withTimeout(client.deleteTemplates([templateId])); + await withTimeout(client.deleteTemplates({ ids: [templateId] })); } catch (cleanupError) { console.warn( `Failed to cleanup ${type} template ${templateId}:`, @@ -384,12 +384,12 @@ describe("Template Management Integration Tests", () => { expect(typeof previewNoData).toBe("string"); expect(previewNoData).toContain("Test Email"); - await withTimeout(client.deleteTemplates([templateId])); + await withTimeout(client.deleteTemplates({ ids: [templateId] })); templateId = undefined; } catch (error) { if (templateId) { try { - await withTimeout(client.deleteTemplates([templateId])); + await withTimeout(client.deleteTemplates({ ids: [templateId] })); } catch (cleanupError) { logger.warn( `Failed to cleanup email template ${templateId}:`, @@ -429,12 +429,12 @@ describe("Template Management Integration Tests", () => { expect(typeof previewNoData).toBe("string"); expect(previewNoData).toContain("Test InApp"); - await withTimeout(client.deleteTemplates([templateId])); + await withTimeout(client.deleteTemplates({ ids: [templateId] })); templateId = undefined; } catch (error) { if (templateId) { try { - await withTimeout(client.deleteTemplates([templateId])); + await withTimeout(client.deleteTemplates({ ids: [templateId] })); } catch (cleanupError) { logger.warn( `Failed to cleanup in-app template ${templateId}:`, diff --git a/tests/integration/users.test.ts b/tests/integration/users.test.ts index 237ccf9..c6c954f 100644 --- a/tests/integration/users.test.ts +++ b/tests/integration/users.test.ts @@ -68,7 +68,7 @@ describe("User Management Integration Tests", () => { // ✅ VERIFY: User can be retrieved by email const userResponse = await withTimeout( - client.getUserByEmail(testUserEmail) + client.getUserByEmail({ email: testUserEmail }) ); expect(userResponse.user?.email).toBe(testUserEmail); expect(userResponse.user?.dataFields?.testField).toBe("email-test"); @@ -89,7 +89,7 @@ describe("User Management Integration Tests", () => { }); // ✅ VERIFY: User can be retrieved by userId - const userResponse = await withTimeout(client.getUserByUserId(testUserId)); + const userResponse = await withTimeout(client.getUserByUserId({ userId: testUserId })); expect(userResponse.user?.userId).toBe(testUserId); expect(userResponse.user?.email).toBe(testUserEmail); expect(userResponse.user?.dataFields?.testField).toBe("userId-test"); @@ -239,7 +239,7 @@ describe("User Management Integration Tests", () => { // Delete the user const deleteResponse = await withTimeout( - client.deleteUserByEmail(deleteTestEmail) + client.deleteUserByEmail({ email: deleteTestEmail }) ); expect(deleteResponse.code).toBe("Success"); @@ -268,7 +268,7 @@ describe("User Management Integration Tests", () => { // Also verify we can retrieve by userId before deleting (with retry for eventual consistency) await retryWithBackoff( async () => { - const userCheck = await client.getUserByUserId(deleteTestUserId); + const userCheck = await client.getUserByUserId({ userId: deleteTestUserId }); if (!userCheck.user?.userId) { throw new Error("userId not set on user profile yet"); } @@ -283,7 +283,7 @@ describe("User Management Integration Tests", () => { // Delete the user by userId with retry in case of timing issues const deleteResponse = await retryWithBackoff( async () => { - return await client.deleteUserByUserId(deleteTestUserId); + return await client.deleteUserByUserId({ userId: deleteTestUserId }); }, { description: `Delete user by userId ${deleteTestUserId}`, @@ -329,7 +329,7 @@ describe("User Management Integration Tests", () => { // Note: There may be some delay in email updates await new Promise((resolve) => setTimeout(resolve, 2000)); - const userResponse = await withTimeout(client.getUserByEmail(newEmail)); + const userResponse = await withTimeout(client.getUserByEmail({ email: newEmail })); expect(userResponse.user?.email).toBe(newEmail); } finally { // Cleanup both possible emails diff --git a/tests/unit/catalogs.test.ts b/tests/unit/catalogs.test.ts index b9e63eb..265f94d 100644 --- a/tests/unit/catalogs.test.ts +++ b/tests/unit/catalogs.test.ts @@ -39,7 +39,7 @@ describe("Catalog Operations", () => { }; mockAxiosInstance.post.mockResolvedValue(mockResponse); - const result = await client.createCatalog("test-catalog"); + const result = await client.createCatalog({ catalogName: "test-catalog" }); expect(mockAxiosInstance.post).toHaveBeenCalledWith( "/api/catalogs/test-catalog" @@ -56,7 +56,7 @@ describe("Catalog Operations", () => { }; mockAxiosInstance.post.mockResolvedValue(mockResponse); - await client.createCatalog("test catalog/with+special"); + await client.createCatalog({ catalogName: "test catalog/with+special" }); expect(mockAxiosInstance.post).toHaveBeenCalledWith( "/api/catalogs/test%20catalog%2Fwith%2Bspecial" @@ -99,7 +99,10 @@ describe("Catalog Operations", () => { }; mockAxiosInstance.get.mockResolvedValue(mockResponse); - const result = await client.getCatalogItem("products", "item1"); + const result = await client.getCatalogItem({ + catalogName: "products", + itemId: "item1", + }); expect(mockAxiosInstance.get).toHaveBeenCalledWith( "/api/catalogs/products/items/item1" @@ -119,7 +122,10 @@ describe("Catalog Operations", () => { }; mockAxiosInstance.get.mockResolvedValue(mockResponse); - await client.getCatalogItem("my catalog", "item/1"); + await client.getCatalogItem({ + catalogName: "my catalog", + itemId: "item/1", + }); expect(mockAxiosInstance.get).toHaveBeenCalledWith( "/api/catalogs/my%20catalog/items/item%2F1" @@ -137,7 +143,10 @@ describe("Catalog Operations", () => { }; mockAxiosInstance.delete.mockResolvedValue(mockResponse); - const result = await client.deleteCatalogItem("products", "item1"); + const result = await client.deleteCatalogItem({ + catalogName: "products", + itemId: "item1", + }); expect(mockAxiosInstance.delete).toHaveBeenCalledWith( "/api/catalogs/products/items/item1" @@ -154,7 +163,10 @@ describe("Catalog Operations", () => { }; mockAxiosInstance.delete.mockResolvedValue(mockResponse); - await client.deleteCatalogItem("my catalog", "item+1"); + await client.deleteCatalogItem({ + catalogName: "my catalog", + itemId: "item+1", + }); expect(mockAxiosInstance.delete).toHaveBeenCalledWith( "/api/catalogs/my%20catalog/items/item%2B1" @@ -427,7 +439,10 @@ describe("Catalog Operations", () => { const expectedError = createIterableError(axiosError); mockAxiosInstance.get.mockRejectedValue(expectedError); - const promise = client.getCatalogItem("nonexistent", "item123"); + const promise = client.getCatalogItem({ + catalogName: "nonexistent", + itemId: "item123", + }); await expect(promise).rejects.toThrow(IterableApiError); try { @@ -452,7 +467,7 @@ describe("Catalog Operations", () => { }; mockAxiosInstance.delete.mockResolvedValue(mockResponse); - const result = await client.deleteCatalog("test-catalog"); + const result = await client.deleteCatalog({ catalogName: "test-catalog" }); expect(mockAxiosInstance.delete).toHaveBeenCalledWith( "/api/catalogs/test-catalog" @@ -469,7 +484,7 @@ describe("Catalog Operations", () => { }; mockAxiosInstance.delete.mockResolvedValue(mockResponse); - await client.deleteCatalog("test catalog with spaces"); + await client.deleteCatalog({ catalogName: "test catalog with spaces" }); expect(mockAxiosInstance.delete).toHaveBeenCalledWith( "/api/catalogs/test%20catalog%20with%20spaces" diff --git a/tests/unit/templates.test.ts b/tests/unit/templates.test.ts index 761b3dc..cc3e163 100644 --- a/tests/unit/templates.test.ts +++ b/tests/unit/templates.test.ts @@ -132,7 +132,7 @@ describe("Template Management", () => { }; mockAxiosInstance.post.mockResolvedValue(mockResponse); - const result = await client.deleteTemplates(templateIds); + const result = await client.deleteTemplates({ ids: templateIds }); expect(mockAxiosInstance.post).toHaveBeenCalledWith( "/api/templates/bulkDelete", diff --git a/tests/unit/users.test.ts b/tests/unit/users.test.ts index be8e358..f076d8e 100644 --- a/tests/unit/users.test.ts +++ b/tests/unit/users.test.ts @@ -35,11 +35,10 @@ describe("User Management", () => { const mockResponse = { data: { user: { email: emailWithSpecialChars } } }; mockAxiosInstance.get.mockResolvedValue(mockResponse); - await client.getUserByEmail(emailWithSpecialChars); + await client.getUserByEmail({ email: emailWithSpecialChars }); expect(mockAxiosInstance.get).toHaveBeenCalledWith( - `/api/users/${encodeURIComponent(emailWithSpecialChars)}`, - { signal: undefined } + `/api/users/${encodeURIComponent(emailWithSpecialChars)}` ); }); @@ -55,7 +54,7 @@ describe("User Management", () => { }; mockAxiosInstance.get.mockResolvedValue(mockResponse); - const result = await client.getUserByEmail(TEST_USER_EMAIL); + const result = await client.getUserByEmail({ email: TEST_USER_EMAIL }); expect(result.user?.email).toBe(TEST_USER_EMAIL); expect(result.user?.userId).toBe("user123"); @@ -70,11 +69,10 @@ describe("User Management", () => { }; mockAxiosInstance.get.mockResolvedValue(mockResponse); - await client.getUserByUserId(userId); + await client.getUserByUserId({ userId }); expect(mockAxiosInstance.get).toHaveBeenCalledWith( - `/api/users/byUserId/${userId}`, - {} + `/api/users/byUserId/${encodeURIComponent(userId)}` ); }); }); @@ -85,7 +83,7 @@ describe("User Management", () => { const mockResponse = { data: { code: "Success", msg: "Deleted" } }; mockAxiosInstance.delete.mockResolvedValue(mockResponse); - await client.deleteUserByEmail(emailWithSpecialChars); + await client.deleteUserByEmail({ email: emailWithSpecialChars }); expect(mockAxiosInstance.delete).toHaveBeenCalledWith( `/api/users/${encodeURIComponent(emailWithSpecialChars)}` @@ -99,7 +97,7 @@ describe("User Management", () => { const mockResponse = { data: { code: "Success", msg: "Deleted" } }; mockAxiosInstance.delete.mockResolvedValue(mockResponse); - await client.deleteUserByUserId(userId); + await client.deleteUserByUserId({ userId }); expect(mockAxiosInstance.delete).toHaveBeenCalledWith( `/api/users/byUserId/${encodeURIComponent(userId)}` diff --git a/tests/utils/test-helpers.ts b/tests/utils/test-helpers.ts index 20797ed..1308d45 100644 --- a/tests/utils/test-helpers.ts +++ b/tests/utils/test-helpers.ts @@ -88,7 +88,7 @@ export async function cleanupTestUser(client: IterableClient, email: string) { } try { - await client.deleteUserByEmail(email); + await client.deleteUserByEmail({ email }); logger.debug(`Cleaned up test user: ${email}`); } catch (error) { logger.warn(`Failed to cleanup user ${email}:`, error); @@ -286,7 +286,7 @@ export async function waitForUserUpdate( ): Promise { return retryWithBackoff( async () => { - const userResponse = await client.getUserByEmail(email); + const userResponse = await client.getUserByEmail({ email }); const actualDataFields = userResponse.user?.dataFields || {}; const missingFields = Object.entries(expectedDataFields).filter( ([key, expectedValue]) => actualDataFields[key] !== expectedValue