From 42744546768a3c022f110b9952792935a42538fe Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 17 Mar 2026 19:35:18 +0000 Subject: [PATCH 1/2] Initial plan From 940a28633639a0a7684adcb29bb0eb9220869842 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 17 Mar 2026 19:47:56 +0000 Subject: [PATCH 2/2] refactor: simplify conditional rendering logic and add showNavigateButton getter - Remove redundant `if:false={isFullLock}` nested inside `if:true={isDismissible}` blocks (close button in header and dismiss button in footer), since `isDismissible = !isFullLock && (...)` already guarantees isFullLock=false when isDismissible=true. - Replace double-negative `if:false={isDismissible}` + `if:false={isFullLock}` in the footer with a single `if:true={showNavigateButton}` using a new named getter. - Add `get showNavigateButton()` getter (!isDismissible && !isFullLock) as the single source of truth for the app-lock navigate state. - Add focused Jest tests covering all three footer-button rendering scenarios. Co-authored-by: ethandunzer <180557240+ethandunzer@users.noreply.github.com> --- .../scheduledMaintenanceComponent.test.js | 105 +- .../scheduledMaintenanceComponent.html | 20 +- .../scheduledMaintenanceComponent.js | 6 + package-lock.json | 9825 +++++++++++++++++ 4 files changed, 9942 insertions(+), 14 deletions(-) create mode 100644 package-lock.json diff --git a/force-app/main/default/lwc/scheduledMaintenanceComponent/__tests__/scheduledMaintenanceComponent.test.js b/force-app/main/default/lwc/scheduledMaintenanceComponent/__tests__/scheduledMaintenanceComponent.test.js index 6b8c587..9233efe 100644 --- a/force-app/main/default/lwc/scheduledMaintenanceComponent/__tests__/scheduledMaintenanceComponent.test.js +++ b/force-app/main/default/lwc/scheduledMaintenanceComponent/__tests__/scheduledMaintenanceComponent.test.js @@ -1,12 +1,72 @@ import { createElement } from 'lwc'; import ScheduledMaintenanceComponent from 'c/scheduledMaintenanceComponent'; +import getActiveScheduledMaintenances from '@salesforce/apex/ScheduledMaintenanceService.getActiveScheduledMaintenances'; +import getAppIdByDeveloperName from '@salesforce/apex/ScheduledMaintenanceService.getAppIdByDeveloperName'; +import getUserLocaleInfo from '@salesforce/apex/ScheduledMaintenanceService.getUserLocaleInfo'; + +jest.mock( + '@salesforce/apex/ScheduledMaintenanceService.getActiveScheduledMaintenances', + () => ({ default: jest.fn() }), + { virtual: true } +); +jest.mock( + '@salesforce/apex/ScheduledMaintenanceService.getAppIdByDeveloperName', + () => ({ default: jest.fn() }), + { virtual: true } +); +jest.mock( + '@salesforce/apex/ScheduledMaintenanceService.getUserLocaleInfo', + () => ({ default: jest.fn() }), + { virtual: true } +); + +// Flush all pending promise microtasks +async function flushPromises() { + for (let i = 0; i < 10; i++) { + // eslint-disable-next-line no-await-in-loop + await Promise.resolve(); + } +} + +function isoOffset(ms) { + return new Date(Date.now() + ms).toISOString(); +} + +const HOUR = 60 * 60 * 1000; + +function baseRecord(overrides = {}) { + return { + Id: 'rec001', + Start_Date_Time__c: isoOffset(-HOUR), + End_Date_Time__c: isoOffset(HOUR), + Dismissible__c: true, + Applicable_Apps__c: 'TestApp', + Alert_Frequency__c: 'Every Visit', + Subject__c: 'Test Maintenance', + Description__c: 'Test description', + Alert_Buffer__c: 0, + ...overrides + }; +} + +// Find a lightning-button stub element by its label property +function findButtonByLabel(root, label) { + return Array.from(root.querySelectorAll('lightning-button')).find(el => el.label === label) || null; +} describe('c-scheduled-maintenance-component', () => { + beforeEach(() => { + // Provide safe default mocks so tests that don't care about Apex don't throw + getActiveScheduledMaintenances.mockResolvedValue([]); + getAppIdByDeveloperName.mockResolvedValue(null); + getUserLocaleInfo.mockResolvedValue({ timeZone: 'UTC', locale: 'en-US' }); + }); + afterEach(() => { - // The jsdom instance is shared across test cases in a single file so reset the DOM while (document.body.firstChild) { document.body.removeChild(document.body.firstChild); } + jest.clearAllMocks(); }); it('TODO: test case generated by CLI command, please fill in test logic', () => { @@ -22,4 +82,47 @@ describe('c-scheduled-maintenance-component', () => { // const div = element.shadowRoot.querySelector('div'); expect(1).toBe(1); }); + + // --- Footer button rendering driven by showNavigateButton / isDismissible --- + + describe('footer button rendering', () => { + beforeEach(() => { + jest.useFakeTimers(); + }); + + afterEach(() => { + jest.useRealTimers(); + }); + + async function mountWith(records) { + getActiveScheduledMaintenances.mockResolvedValue(records); + const element = createElement('c-scheduled-maintenance-component', { + is: ScheduledMaintenanceComponent + }); + document.body.appendChild(element); + await flushPromises(); + return element; + } + + it('shows Dismiss button and hides Navigate button when active maintenance is dismissible', async () => { + const el = await mountWith([baseRecord({ Dismissible__c: true })]); + + expect(findButtonByLabel(el.shadowRoot, 'Dismiss')).not.toBeNull(); + expect(findButtonByLabel(el.shadowRoot, 'Navigate to Welcome App')).toBeNull(); + }); + + it('shows Navigate button and hides Dismiss button for a non-system app-lock (isDismissible=false, isFullLock=false)', async () => { + const el = await mountWith([baseRecord({ Dismissible__c: false, Applicable_Apps__c: 'App1' })]); + + expect(findButtonByLabel(el.shadowRoot, 'Navigate to Welcome App')).not.toBeNull(); + expect(findButtonByLabel(el.shadowRoot, 'Dismiss')).toBeNull(); + }); + + it('hides both buttons during a full system lock (isDismissible=false, isFullLock=true)', async () => { + const el = await mountWith([baseRecord({ Dismissible__c: false, Applicable_Apps__c: 'System' })]); + + expect(findButtonByLabel(el.shadowRoot, 'Navigate to Welcome App')).toBeNull(); + expect(findButtonByLabel(el.shadowRoot, 'Dismiss')).toBeNull(); + }); + }); }); \ No newline at end of file diff --git a/force-app/main/default/lwc/scheduledMaintenanceComponent/scheduledMaintenanceComponent.html b/force-app/main/default/lwc/scheduledMaintenanceComponent/scheduledMaintenanceComponent.html index b2bc45c..810f3ae 100644 --- a/force-app/main/default/lwc/scheduledMaintenanceComponent/scheduledMaintenanceComponent.html +++ b/force-app/main/default/lwc/scheduledMaintenanceComponent/scheduledMaintenanceComponent.html @@ -5,12 +5,10 @@

{title}