From b9cadf002cede05cb6f14562dc001f52a75e626f Mon Sep 17 00:00:00 2001 From: Luca <102960244+Luca-Timo@users.noreply.github.com> Date: Tue, 26 May 2026 19:07:31 +0200 Subject: [PATCH] test(crm): update mocks for new createInvitation + OG date-format behavior MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Two upstream tests regressed because the CRM PR added expected behavior they didn't anticipate: - galleryOgService.shareImage.test.js: formatEventDate is now async and routes through utils/dateFormatter so the OG card respects the admin's general_date_format setting (per feedback_respect_general_format_settings). That adds a third db('app_settings') call on every buildOgMetadata path. Mock the formatter module directly — the format itself is irrelevant to the cover-vs-logo contract this file pins. - customerAccountsService.test.js: createInvitation now allows a duplicate email when the existing row is PASSIVE (password_hash IS NULL) — that's the "promote passive customer to portal" path. The active-customer rejection mock now has to set password_hash so the guard fires. Both are test-only changes; no service code touched. --- backend/src/__tests__/customerAccountsService.test.js | 6 +++++- backend/src/__tests__/galleryOgService.shareImage.test.js | 8 ++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/backend/src/__tests__/customerAccountsService.test.js b/backend/src/__tests__/customerAccountsService.test.js index 4a236c4d..4963e136 100644 --- a/backend/src/__tests__/customerAccountsService.test.js +++ b/backend/src/__tests__/customerAccountsService.test.js @@ -66,7 +66,11 @@ beforeEach(() => { describe('createInvitation', () => { it('rejects when a customer with the email already exists', async () => { const svc = require('../services/customerAccountsService'); - db.mockImplementationOnce(() => chain({ first: { id: 1, email: 'taken@example.com' } })); + // Service only rejects when the existing row has a password_hash — + // a passive (password_hash = null) row is the "promote to portal" + // path and is allowed through. Pin the rejection contract by mocking + // an active row. + db.mockImplementationOnce(() => chain({ first: { id: 1, email: 'taken@example.com', password_hash: 'hash' } })); await expect( svc.createInvitation({ email: 'taken@example.com', invitedById: 9 }) ).rejects.toThrow(/already exists/i); diff --git a/backend/src/__tests__/galleryOgService.shareImage.test.js b/backend/src/__tests__/galleryOgService.shareImage.test.js index c6c8b60e..8b2d04fa 100644 --- a/backend/src/__tests__/galleryOgService.shareImage.test.js +++ b/backend/src/__tests__/galleryOgService.shareImage.test.js @@ -29,6 +29,14 @@ jest.mock('../services/storage', () => ({ getStorage: jest.fn(), })); +// dateFormatter.formatDate queries `app_settings` for general_date_format, +// which would add a third unmocked db() call to every buildOgMetadata path. +// The format itself is irrelevant to the cover-vs-logo contract this file +// pins — short-circuit it to a stable string so the tests stay focused. +jest.mock('../utils/dateFormatter', () => ({ + formatDate: jest.fn().mockResolvedValue('12.06.2026'), +})); + const { db } = require('../database/db'); const { ensureThumbnail } = require('../services/imageProcessor'); const { getStorage } = require('../services/storage');