import axios from 'axios'; import { CoolCommException } from '@cool-midway/core'; import { CrmHubSpotService } from '../../../src/modules/crm/service/hubspot'; describe('CrmHubSpotService.createContact', () => { let service: CrmHubSpotService; beforeEach(() => { service = new CrmHubSpotService(); jest.clearAllMocks(); }); afterEach(() => { jest.restoreAllMocks(); }); it('accessToken 为空时应抛出 CoolCommException,说明未配置 HubSpot', async () => { const postSpy = jest.spyOn(axios, 'post'); await expect( service.createContact('', { properties: { email: 'a@b.com' }, }) ).rejects.toThrow(CoolCommException); await expect( service.createContact(' ', { properties: { email: 'a@b.com' }, }) ).rejects.toThrow(/HubSpot/); expect(postSpy).not.toHaveBeenCalled(); }); it('有 token 时应向 HubSpot Contacts API 发起 Bearer 请求并返回 id 与原始响应', async () => { const token = 'pat-test-token-xyz'; const payload = { properties: { email: 'john@acme.com', firstname: 'John', }, }; const raw = { id: 'hs-contact-99', properties: payload.properties }; const postSpy = jest.spyOn(axios, 'post').mockResolvedValueOnce({ status: 201, data: raw, }); const result = await service.createContact(token, payload); expect(postSpy).toHaveBeenCalledTimes(1); const [url, body, config] = postSpy.mock.calls[0]; expect(url).toBe('https://api.hubapi.com/crm/v3/objects/contacts'); expect(body).toEqual(payload); expect(config?.headers?.Authorization).toBe(`Bearer ${token}`); expect(config?.timeout).toBe(8000); expect(result.id).toBe('hs-contact-99'); expect(result.raw).toEqual(raw); }); it('对方返回 4xx 时应抛出包含状态码与错误信息的异常,不吞掉', async () => { const axiosError = Object.assign(new Error('Request failed with status code 400'), { isAxiosError: true, response: { status: 400, data: { message: 'Property values were not valid' }, }, }); jest.spyOn(axios, 'post').mockRejectedValueOnce(axiosError); await expect( service.createContact('pat-valid', { properties: { email: 'bad' }, }) ).rejects.toThrow(/400|Property values were not valid/); }); });