diff --git a/src/components/IdentitySection.vue b/src/components/IdentitySection.vue
index 0ad5962c..d0a173ed 100644
--- a/src/components/IdentitySection.vue
+++ b/src/components/IdentitySection.vue
@@ -55,10 +55,7 @@
aria-label="Delete profile image"
@click="deleteImage"
>
-
+
diff --git a/src/libs/util.ts b/src/libs/util.ts
index e9dc22cf..8a84a77e 100644
--- a/src/libs/util.ts
+++ b/src/libs/util.ts
@@ -973,28 +973,28 @@ export async function importFromMnemonic(
if (isTestUser0) {
// Set up Test User #0 specific settings with enhanced error handling
const platformService = await getPlatformService();
-
+
try {
// First, ensure the DID-specific settings record exists
await platformService.insertDidSpecificSettings(newId.did);
-
+
// Then update with Test User #0 specific settings
await platformService.updateDidSpecificSettings(newId.did, {
firstName: "User Zero",
isRegistered: true,
});
-
+
// Verify the settings were saved correctly
const verificationResult = await platformService.dbQuery(
"SELECT firstName, isRegistered FROM settings WHERE accountDid = ?",
[newId.did],
);
-
+
if (verificationResult?.values?.length) {
const settings = verificationResult.values[0];
const firstName = settings[0];
const isRegistered = settings[1];
-
+
logger.info("[importFromMnemonic] Test User #0 settings verification", {
did: newId.did,
firstName,
@@ -1002,40 +1002,50 @@ export async function importFromMnemonic(
expectedFirstName: "User Zero",
expectedIsRegistered: true,
});
-
+
// If settings weren't saved correctly, try individual updates
if (firstName !== "User Zero" || isRegistered !== 1) {
- logger.warn("[importFromMnemonic] Test User #0 settings not saved correctly, retrying with individual updates");
-
+ logger.warn(
+ "[importFromMnemonic] Test User #0 settings not saved correctly, retrying with individual updates",
+ );
+
await platformService.dbExec(
"UPDATE settings SET firstName = ? WHERE accountDid = ?",
["User Zero", newId.did],
);
-
+
await platformService.dbExec(
"UPDATE settings SET isRegistered = ? WHERE accountDid = ?",
[1, newId.did],
);
-
+
// Verify again
const retryResult = await platformService.dbQuery(
"SELECT firstName, isRegistered FROM settings WHERE accountDid = ?",
[newId.did],
);
-
+
if (retryResult?.values?.length) {
const retrySettings = retryResult.values[0];
- logger.info("[importFromMnemonic] Test User #0 settings after retry", {
- firstName: retrySettings[0],
- isRegistered: retrySettings[1],
- });
+ logger.info(
+ "[importFromMnemonic] Test User #0 settings after retry",
+ {
+ firstName: retrySettings[0],
+ isRegistered: retrySettings[1],
+ },
+ );
}
}
} else {
- logger.error("[importFromMnemonic] Failed to verify Test User #0 settings - no record found");
+ logger.error(
+ "[importFromMnemonic] Failed to verify Test User #0 settings - no record found",
+ );
}
} catch (error) {
- logger.error("[importFromMnemonic] Error setting up Test User #0 settings:", error);
+ logger.error(
+ "[importFromMnemonic] Error setting up Test User #0 settings:",
+ error,
+ );
// Don't throw - allow the import to continue even if settings fail
}
}
diff --git a/src/test/ContactBulkActions.test.ts b/src/test/ContactBulkActions.test.ts
index bbde0daa..4730474c 100644
--- a/src/test/ContactBulkActions.test.ts
+++ b/src/test/ContactBulkActions.test.ts
@@ -1,25 +1,24 @@
-import { describe, it, expect, beforeEach, vi } from 'vitest'
-import { mount } from '@vue/test-utils'
-import ContactBulkActions from '@/components/ContactBulkActions.vue'
-import { createMockContacts } from '@/test/factories/contactFactory'
+import { describe, it, expect, beforeEach } from "vitest";
+import { mount } from "@vue/test-utils";
+import ContactBulkActions from "@/components/ContactBulkActions.vue";
/**
* ContactBulkActions Component Tests
- *
+ *
* Comprehensive test suite for the ContactBulkActions component.
* Tests component rendering, props, events, and user interactions.
- *
+ *
* @author Matthew Raymer
*/
-describe('ContactBulkActions', () => {
- let wrapper: any
+describe("ContactBulkActions", () => {
+ let wrapper: any;
/**
* Test setup - creates a fresh component instance before each test
*/
beforeEach(() => {
- wrapper = null
- })
+ wrapper = null;
+ });
/**
* Helper function to mount component with props
@@ -31,482 +30,490 @@ describe('ContactBulkActions', () => {
props: {
showGiveNumbers: false,
allContactsSelected: false,
- copyButtonClass: 'btn-primary',
+ copyButtonClass: "btn-primary",
copyButtonDisabled: false,
- ...props
- }
- })
- }
-
- /**
- * Test data factory for consistent test data
- */
- const createTestProps = (overrides = {}) => ({
- showGiveNumbers: false,
- allContactsSelected: false,
- copyButtonClass: 'btn-primary',
- copyButtonDisabled: false,
- ...overrides
- })
-
- describe('Component Rendering', () => {
- it('should render when all props are provided', () => {
- wrapper = mountComponent()
-
- expect(wrapper.exists()).toBe(true)
- expect(wrapper.find('div').exists()).toBe(true)
- })
-
- it('should render checkbox when showGiveNumbers is false', () => {
- wrapper = mountComponent({ showGiveNumbers: false })
-
- expect(wrapper.find('input[type="checkbox"]').exists()).toBe(true)
- })
-
- it('should not render checkbox when showGiveNumbers is true', () => {
- wrapper = mountComponent({ showGiveNumbers: true })
-
- expect(wrapper.find('input[type="checkbox"]').exists()).toBe(false)
- })
-
- it('should render copy button when showGiveNumbers is false', () => {
- wrapper = mountComponent({ showGiveNumbers: false })
-
- expect(wrapper.find('button').exists()).toBe(true)
- expect(wrapper.find('button').text()).toBe('Copy')
- })
-
- it('should not render copy button when showGiveNumbers is true', () => {
- wrapper = mountComponent({ showGiveNumbers: true })
-
- expect(wrapper.find('button').exists()).toBe(false)
- })
- })
-
- describe('Component Styling', () => {
- it('should have correct container CSS classes', () => {
- wrapper = mountComponent()
- const container = wrapper.find('div')
-
- expect(container.classes()).toContain('mt-2')
- expect(container.classes()).toContain('w-full')
- expect(container.classes()).toContain('text-left')
- })
-
- it('should have correct checkbox CSS classes', () => {
- wrapper = mountComponent()
- const checkbox = wrapper.find('input[type="checkbox"]')
-
- expect(checkbox.classes()).toContain('align-middle')
- expect(checkbox.classes()).toContain('ml-2')
- expect(checkbox.classes()).toContain('h-6')
- expect(checkbox.classes()).toContain('w-6')
- })
-
- it('should apply custom copy button class', () => {
- wrapper = mountComponent({ copyButtonClass: 'custom-btn-class' })
- const button = wrapper.find('button')
-
- expect(button.classes()).toContain('custom-btn-class')
- })
- })
-
- describe('Component Props', () => {
- it('should accept showGiveNumbers prop', () => {
- wrapper = mountComponent({ showGiveNumbers: true })
- expect(wrapper.vm.showGiveNumbers).toBe(true)
- })
-
- it('should accept allContactsSelected prop', () => {
- wrapper = mountComponent({ allContactsSelected: true })
- expect(wrapper.vm.allContactsSelected).toBe(true)
- })
-
- it('should accept copyButtonClass prop', () => {
- wrapper = mountComponent({ copyButtonClass: 'test-class' })
- expect(wrapper.vm.copyButtonClass).toBe('test-class')
- })
-
- it('should accept copyButtonDisabled prop', () => {
- wrapper = mountComponent({ copyButtonDisabled: true })
- expect(wrapper.vm.copyButtonDisabled).toBe(true)
- })
-
- it('should handle all props together', () => {
+ ...props,
+ },
+ });
+ };
+
+ describe("Component Rendering", () => {
+ it("should render when all props are provided", () => {
+ wrapper = mountComponent();
+
+ expect(wrapper.exists()).toBe(true);
+ expect(wrapper.find("div").exists()).toBe(true);
+ });
+
+ it("should render checkbox when showGiveNumbers is false", () => {
+ wrapper = mountComponent({ showGiveNumbers: false });
+
+ expect(wrapper.find('input[type="checkbox"]').exists()).toBe(true);
+ });
+
+ it("should not render checkbox when showGiveNumbers is true", () => {
+ wrapper = mountComponent({ showGiveNumbers: true });
+
+ expect(wrapper.find('input[type="checkbox"]').exists()).toBe(false);
+ });
+
+ it("should render copy button when showGiveNumbers is false", () => {
+ wrapper = mountComponent({ showGiveNumbers: false });
+
+ expect(wrapper.find("button").exists()).toBe(true);
+ expect(wrapper.find("button").text()).toBe("Copy");
+ });
+
+ it("should not render copy button when showGiveNumbers is true", () => {
+ wrapper = mountComponent({ showGiveNumbers: true });
+
+ expect(wrapper.find("button").exists()).toBe(false);
+ });
+ });
+
+ describe("Component Styling", () => {
+ it("should have correct container CSS classes", () => {
+ wrapper = mountComponent();
+ const container = wrapper.find("div");
+
+ expect(container.classes()).toContain("mt-2");
+ expect(container.classes()).toContain("w-full");
+ expect(container.classes()).toContain("text-left");
+ });
+
+ it("should have correct checkbox CSS classes", () => {
+ wrapper = mountComponent();
+ const checkbox = wrapper.find('input[type="checkbox"]');
+
+ expect(checkbox.classes()).toContain("align-middle");
+ expect(checkbox.classes()).toContain("ml-2");
+ expect(checkbox.classes()).toContain("h-6");
+ expect(checkbox.classes()).toContain("w-6");
+ });
+
+ it("should apply custom copy button class", () => {
+ wrapper = mountComponent({ copyButtonClass: "custom-btn-class" });
+ const button = wrapper.find("button");
+
+ expect(button.classes()).toContain("custom-btn-class");
+ });
+ });
+
+ describe("Component Props", () => {
+ it("should accept showGiveNumbers prop", () => {
+ wrapper = mountComponent({ showGiveNumbers: true });
+ expect(wrapper.vm.showGiveNumbers).toBe(true);
+ });
+
+ it("should accept allContactsSelected prop", () => {
+ wrapper = mountComponent({ allContactsSelected: true });
+ expect(wrapper.vm.allContactsSelected).toBe(true);
+ });
+
+ it("should accept copyButtonClass prop", () => {
+ wrapper = mountComponent({ copyButtonClass: "test-class" });
+ expect(wrapper.vm.copyButtonClass).toBe("test-class");
+ });
+
+ it("should accept copyButtonDisabled prop", () => {
+ wrapper = mountComponent({ copyButtonDisabled: true });
+ expect(wrapper.vm.copyButtonDisabled).toBe(true);
+ });
+
+ it("should handle all props together", () => {
wrapper = mountComponent({
showGiveNumbers: true,
allContactsSelected: true,
- copyButtonClass: 'test-class',
- copyButtonDisabled: true
- })
-
- expect(wrapper.vm.showGiveNumbers).toBe(true)
- expect(wrapper.vm.allContactsSelected).toBe(true)
- expect(wrapper.vm.copyButtonClass).toBe('test-class')
- expect(wrapper.vm.copyButtonDisabled).toBe(true)
- })
- })
-
- describe('Checkbox Behavior', () => {
- it('should be checked when allContactsSelected is true', () => {
- wrapper = mountComponent({ allContactsSelected: true })
- const checkbox = wrapper.find('input[type="checkbox"]')
-
- expect(checkbox.element.checked).toBe(true)
- })
-
- it('should not be checked when allContactsSelected is false', () => {
- wrapper = mountComponent({ allContactsSelected: false })
- const checkbox = wrapper.find('input[type="checkbox"]')
-
- expect(checkbox.element.checked).toBe(false)
- })
-
- it('should have correct test ID', () => {
- wrapper = mountComponent()
- const checkbox = wrapper.find('input[type="checkbox"]')
-
- expect(checkbox.attributes('data-testid')).toBe('contactCheckAllBottom')
- })
- })
-
- describe('Button Behavior', () => {
- it('should be disabled when copyButtonDisabled is true', () => {
- wrapper = mountComponent({ copyButtonDisabled: true })
- const button = wrapper.find('button')
-
- expect(button.attributes('disabled')).toBeDefined()
- })
-
- it('should not be disabled when copyButtonDisabled is false', () => {
- wrapper = mountComponent({ copyButtonDisabled: false })
- const button = wrapper.find('button')
-
- expect(button.attributes('disabled')).toBeUndefined()
- })
-
- it('should have correct text', () => {
- wrapper = mountComponent()
- const button = wrapper.find('button')
-
- expect(button.text()).toBe('Copy')
- })
- })
-
- describe('User Interactions', () => {
- it('should emit toggle-all-selection event when checkbox is clicked', async () => {
- wrapper = mountComponent()
- const checkbox = wrapper.find('input[type="checkbox"]')
-
- await checkbox.trigger('click')
-
- expect(wrapper.emitted('toggle-all-selection')).toBeTruthy()
- expect(wrapper.emitted('toggle-all-selection')).toHaveLength(1)
- })
-
- it('should emit copy-selected event when button is clicked', async () => {
- wrapper = mountComponent()
- const button = wrapper.find('button')
-
- await button.trigger('click')
-
- expect(wrapper.emitted('copy-selected')).toBeTruthy()
- expect(wrapper.emitted('copy-selected')).toHaveLength(1)
- })
-
- it('should emit multiple events when clicked multiple times', async () => {
- wrapper = mountComponent()
- const checkbox = wrapper.find('input[type="checkbox"]')
- const button = wrapper.find('button')
-
- await checkbox.trigger('click')
- await button.trigger('click')
- await checkbox.trigger('click')
-
- expect(wrapper.emitted('toggle-all-selection')).toHaveLength(2)
- expect(wrapper.emitted('copy-selected')).toHaveLength(1)
- })
- })
-
- describe('Component Methods', () => {
- it('should have all required props', () => {
- wrapper = mountComponent()
-
- expect(wrapper.vm.showGiveNumbers).toBeDefined()
- expect(wrapper.vm.allContactsSelected).toBeDefined()
- expect(wrapper.vm.copyButtonClass).toBeDefined()
- expect(wrapper.vm.copyButtonDisabled).toBeDefined()
- })
- })
-
- describe('Edge Cases', () => {
- it('should handle rapid clicks efficiently', async () => {
- wrapper = mountComponent()
- const checkbox = wrapper.find('input[type="checkbox"]')
- const button = wrapper.find('button')
-
+ copyButtonClass: "test-class",
+ copyButtonDisabled: true,
+ });
+
+ expect(wrapper.vm.showGiveNumbers).toBe(true);
+ expect(wrapper.vm.allContactsSelected).toBe(true);
+ expect(wrapper.vm.copyButtonClass).toBe("test-class");
+ expect(wrapper.vm.copyButtonDisabled).toBe(true);
+ });
+ });
+
+ describe("Checkbox Behavior", () => {
+ it("should be checked when allContactsSelected is true", () => {
+ wrapper = mountComponent({ allContactsSelected: true });
+ const checkbox = wrapper.find('input[type="checkbox"]');
+
+ expect(checkbox.element.checked).toBe(true);
+ });
+
+ it("should not be checked when allContactsSelected is false", () => {
+ wrapper = mountComponent({ allContactsSelected: false });
+ const checkbox = wrapper.find('input[type="checkbox"]');
+
+ expect(checkbox.element.checked).toBe(false);
+ });
+
+ it("should have correct test ID", () => {
+ wrapper = mountComponent();
+ const checkbox = wrapper.find('input[type="checkbox"]');
+
+ expect(checkbox.attributes("data-testid")).toBe("contactCheckAllBottom");
+ });
+ });
+
+ describe("Button Behavior", () => {
+ it("should be disabled when copyButtonDisabled is true", () => {
+ wrapper = mountComponent({ copyButtonDisabled: true });
+ const button = wrapper.find("button");
+
+ expect(button.attributes("disabled")).toBeDefined();
+ });
+
+ it("should not be disabled when copyButtonDisabled is false", () => {
+ wrapper = mountComponent({ copyButtonDisabled: false });
+ const button = wrapper.find("button");
+
+ expect(button.attributes("disabled")).toBeUndefined();
+ });
+
+ it("should have correct text", () => {
+ wrapper = mountComponent();
+ const button = wrapper.find("button");
+
+ expect(button.text()).toBe("Copy");
+ });
+ });
+
+ describe("User Interactions", () => {
+ it("should emit toggle-all-selection event when checkbox is clicked", async () => {
+ wrapper = mountComponent();
+ const checkbox = wrapper.find('input[type="checkbox"]');
+
+ await checkbox.trigger("click");
+
+ expect(wrapper.emitted("toggle-all-selection")).toBeTruthy();
+ expect(wrapper.emitted("toggle-all-selection")).toHaveLength(1);
+ });
+
+ it("should emit copy-selected event when button is clicked", async () => {
+ wrapper = mountComponent();
+ const button = wrapper.find("button");
+
+ await button.trigger("click");
+
+ expect(wrapper.emitted("copy-selected")).toBeTruthy();
+ expect(wrapper.emitted("copy-selected")).toHaveLength(1);
+ });
+
+ it("should emit multiple events when clicked multiple times", async () => {
+ wrapper = mountComponent();
+ const checkbox = wrapper.find('input[type="checkbox"]');
+ const button = wrapper.find("button");
+
+ await checkbox.trigger("click");
+ await button.trigger("click");
+ await checkbox.trigger("click");
+
+ expect(wrapper.emitted("toggle-all-selection")).toHaveLength(2);
+ expect(wrapper.emitted("copy-selected")).toHaveLength(1);
+ });
+ });
+
+ describe("Component Methods", () => {
+ it("should have all required props", () => {
+ wrapper = mountComponent();
+
+ expect(wrapper.vm.showGiveNumbers).toBeDefined();
+ expect(wrapper.vm.allContactsSelected).toBeDefined();
+ expect(wrapper.vm.copyButtonClass).toBeDefined();
+ expect(wrapper.vm.copyButtonDisabled).toBeDefined();
+ });
+ });
+
+ describe("Edge Cases", () => {
+ it("should handle rapid clicks efficiently", async () => {
+ wrapper = mountComponent();
+ const checkbox = wrapper.find('input[type="checkbox"]');
+ const button = wrapper.find("button");
+
// Simulate rapid clicks
await Promise.all([
- checkbox.trigger('click'),
- button.trigger('click'),
- checkbox.trigger('click')
- ])
-
- expect(wrapper.emitted('toggle-all-selection')).toHaveLength(2)
- expect(wrapper.emitted('copy-selected')).toHaveLength(1)
- })
-
- it('should maintain component state after prop changes', async () => {
- wrapper = mountComponent({ showGiveNumbers: false })
- expect(wrapper.find('input[type="checkbox"]').exists()).toBe(true)
-
- await wrapper.setProps({ showGiveNumbers: true })
- expect(wrapper.find('input[type="checkbox"]').exists()).toBe(false)
-
- await wrapper.setProps({ showGiveNumbers: false })
- expect(wrapper.find('input[type="checkbox"]').exists()).toBe(true)
- })
-
- it('should handle disabled button clicks', async () => {
- wrapper = mountComponent({ copyButtonDisabled: true })
- const button = wrapper.find('button')
-
- await button.trigger('click')
-
+ checkbox.trigger("click"),
+ button.trigger("click"),
+ checkbox.trigger("click"),
+ ]);
+
+ expect(wrapper.emitted("toggle-all-selection")).toHaveLength(2);
+ expect(wrapper.emitted("copy-selected")).toHaveLength(1);
+ });
+
+ it("should maintain component state after prop changes", async () => {
+ wrapper = mountComponent({ showGiveNumbers: false });
+ expect(wrapper.find('input[type="checkbox"]').exists()).toBe(true);
+
+ await wrapper.setProps({ showGiveNumbers: true });
+ expect(wrapper.find('input[type="checkbox"]').exists()).toBe(false);
+
+ await wrapper.setProps({ showGiveNumbers: false });
+ expect(wrapper.find('input[type="checkbox"]').exists()).toBe(true);
+ });
+
+ it("should handle disabled button clicks", async () => {
+ wrapper = mountComponent({ copyButtonDisabled: true });
+ const button = wrapper.find("button");
+
+ await button.trigger("click");
+
// Disabled buttons typically don't emit events
- expect(wrapper.emitted('copy-selected')).toBeUndefined()
- })
- })
-
- describe('Accessibility', () => {
- it('should meet WCAG accessibility standards', () => {
- wrapper = mountComponent()
- const container = wrapper.find('.mt-2')
- const checkbox = wrapper.find('input[type="checkbox"]')
- const button = wrapper.find('button')
-
+ expect(wrapper.emitted("copy-selected")).toBeUndefined();
+ });
+ });
+
+ describe("Accessibility", () => {
+ it("should meet WCAG accessibility standards", () => {
+ wrapper = mountComponent();
+ const container = wrapper.find(".mt-2");
+ const checkbox = wrapper.find('input[type="checkbox"]');
+ const button = wrapper.find("button");
+
// Semantic structure
- expect(container.exists()).toBe(true)
- expect(checkbox.exists()).toBe(true)
- expect(button.exists()).toBe(true)
-
+ expect(container.exists()).toBe(true);
+ expect(checkbox.exists()).toBe(true);
+ expect(button.exists()).toBe(true);
+
// Form control accessibility
- expect(checkbox.attributes('type')).toBe('checkbox')
- expect(checkbox.attributes('data-testid')).toBe('contactCheckAllBottom')
- expect(button.text()).toBe('Copy')
-
+ expect(checkbox.attributes("type")).toBe("checkbox");
+ expect(checkbox.attributes("data-testid")).toBe("contactCheckAllBottom");
+ expect(button.text()).toBe("Copy");
+
// Note: Component has good accessibility but could be enhanced with:
// - aria-label for checkbox, aria-describedby for button
- })
-
- it('should have proper semantic structure', () => {
- wrapper = mountComponent()
-
- expect(wrapper.find('div').exists()).toBe(true)
- expect(wrapper.find('input[type="checkbox"]').exists()).toBe(true)
- expect(wrapper.find('button').exists()).toBe(true)
- })
-
- it('should have proper form controls', () => {
- wrapper = mountComponent()
- const checkbox = wrapper.find('input[type="checkbox"]')
- const button = wrapper.find('button')
-
- expect(checkbox.attributes('type')).toBe('checkbox')
- expect(button.text()).toBe('Copy')
- })
-
- it('should support keyboard navigation', () => {
- wrapper = mountComponent()
- const checkbox = wrapper.find('input[type="checkbox"]')
- const button = wrapper.find('button')
-
+ });
+
+ it("should have proper semantic structure", () => {
+ wrapper = mountComponent();
+
+ expect(wrapper.find("div").exists()).toBe(true);
+ expect(wrapper.find('input[type="checkbox"]').exists()).toBe(true);
+ expect(wrapper.find("button").exists()).toBe(true);
+ });
+
+ it("should have proper form controls", () => {
+ wrapper = mountComponent();
+ const checkbox = wrapper.find('input[type="checkbox"]');
+ const button = wrapper.find("button");
+
+ expect(checkbox.attributes("type")).toBe("checkbox");
+ expect(button.text()).toBe("Copy");
+ });
+
+ it("should support keyboard navigation", () => {
+ wrapper = mountComponent();
+ const checkbox = wrapper.find('input[type="checkbox"]');
+ const button = wrapper.find("button");
+
// Test that controls are clickable (supports keyboard navigation)
- expect(checkbox.exists()).toBe(true)
- expect(button.exists()).toBe(true)
-
+ expect(checkbox.exists()).toBe(true);
+ expect(button.exists()).toBe(true);
+
// Note: Component doesn't have explicit keyboard event handlers
// Keyboard navigation would be handled by browser defaults
// Test that controls are clickable (which supports keyboard navigation)
- checkbox.trigger('click')
- expect(wrapper.emitted('toggle-all-selection')).toBeTruthy()
-
- button.trigger('click')
- expect(wrapper.emitted('copy-selected')).toBeTruthy()
- })
-
- it('should have proper ARIA attributes', () => {
- wrapper = mountComponent()
- const checkbox = wrapper.find('input[type="checkbox"]')
-
+ checkbox.trigger("click");
+ expect(wrapper.emitted("toggle-all-selection")).toBeTruthy();
+
+ button.trigger("click");
+ expect(wrapper.emitted("copy-selected")).toBeTruthy();
+ });
+
+ it("should have proper ARIA attributes", () => {
+ wrapper = mountComponent();
+ const checkbox = wrapper.find('input[type="checkbox"]');
+
// Verify accessibility attributes
- expect(checkbox.attributes('data-testid')).toBe('contactCheckAllBottom')
-
+ expect(checkbox.attributes("data-testid")).toBe("contactCheckAllBottom");
+
// Note: Could be enhanced with aria-label, aria-describedby
- })
+ });
- it('should maintain accessibility with different prop combinations', () => {
+ it("should maintain accessibility with different prop combinations", () => {
const testCases = [
- { showGiveNumbers: false, allContactsSelected: true, copyButtonClass: 'btn-primary', copyButtonDisabled: false },
- { showGiveNumbers: false, allContactsSelected: false, copyButtonClass: 'btn-secondary', copyButtonDisabled: true },
- { showGiveNumbers: true, allContactsSelected: false, copyButtonClass: 'btn-primary', copyButtonDisabled: false }
- ]
-
- testCases.forEach(props => {
- const testWrapper = mountComponent(props)
-
+ {
+ showGiveNumbers: false,
+ allContactsSelected: true,
+ copyButtonClass: "btn-primary",
+ copyButtonDisabled: false,
+ },
+ {
+ showGiveNumbers: false,
+ allContactsSelected: false,
+ copyButtonClass: "btn-secondary",
+ copyButtonDisabled: true,
+ },
+ {
+ showGiveNumbers: true,
+ allContactsSelected: false,
+ copyButtonClass: "btn-primary",
+ copyButtonDisabled: false,
+ },
+ ];
+
+ testCases.forEach((props) => {
+ const testWrapper = mountComponent(props);
+
if (!props.showGiveNumbers) {
// Controls should be accessible when rendered
- const checkbox = testWrapper.find('input[type="checkbox"]')
- const button = testWrapper.find('button')
-
- expect(checkbox.exists()).toBe(true)
- expect(checkbox.attributes('type')).toBe('checkbox')
- expect(checkbox.attributes('data-testid')).toBe('contactCheckAllBottom')
- expect(button.exists()).toBe(true)
- expect(button.text()).toBe('Copy')
+ const checkbox = testWrapper.find('input[type="checkbox"]');
+ const button = testWrapper.find("button");
+
+ expect(checkbox.exists()).toBe(true);
+ expect(checkbox.attributes("type")).toBe("checkbox");
+ expect(checkbox.attributes("data-testid")).toBe(
+ "contactCheckAllBottom",
+ );
+ expect(button.exists()).toBe(true);
+ expect(button.text()).toBe("Copy");
} else {
// Controls should not render when showGiveNumbers is true
- expect(testWrapper.find('input[type="checkbox"]').exists()).toBe(false)
- expect(testWrapper.find('button').exists()).toBe(false)
+ expect(testWrapper.find('input[type="checkbox"]').exists()).toBe(
+ false,
+ );
+ expect(testWrapper.find("button").exists()).toBe(false);
}
- })
- })
+ });
+ });
+
+ it("should have sufficient color contrast", () => {
+ wrapper = mountComponent();
+ const container = wrapper.find(".mt-2");
- it('should have sufficient color contrast', () => {
- wrapper = mountComponent()
- const container = wrapper.find('.mt-2')
-
// Verify container has proper styling
- expect(container.classes()).toContain('mt-2')
- expect(container.classes()).toContain('w-full')
- expect(container.classes()).toContain('text-left')
- })
-
- it('should have descriptive content', () => {
- wrapper = mountComponent()
- const button = wrapper.find('button')
-
+ expect(container.classes()).toContain("mt-2");
+ expect(container.classes()).toContain("w-full");
+ expect(container.classes()).toContain("text-left");
+ });
+
+ it("should have descriptive content", () => {
+ wrapper = mountComponent();
+ const button = wrapper.find("button");
+
// Button should have descriptive text
- expect(button.exists()).toBe(true)
- expect(button.text()).toBe('Copy')
- })
- })
-
- describe('Conditional Rendering', () => {
- it('should show both controls when showGiveNumbers is false', () => {
- wrapper = mountComponent({ showGiveNumbers: false })
-
- expect(wrapper.find('input[type="checkbox"]').exists()).toBe(true)
- expect(wrapper.find('button').exists()).toBe(true)
- })
-
- it('should hide both controls when showGiveNumbers is true', () => {
- wrapper = mountComponent({ showGiveNumbers: true })
-
- expect(wrapper.find('input[type="checkbox"]').exists()).toBe(false)
- expect(wrapper.find('button').exists()).toBe(false)
- })
- })
-
- describe('Error Handling', () => {
- it('should handle null props gracefully', () => {
- wrapper = mountComponent({
- showGiveNumbers: null as any,
+ expect(button.exists()).toBe(true);
+ expect(button.text()).toBe("Copy");
+ });
+ });
+
+ describe("Conditional Rendering", () => {
+ it("should show both controls when showGiveNumbers is false", () => {
+ wrapper = mountComponent({ showGiveNumbers: false });
+
+ expect(wrapper.find('input[type="checkbox"]').exists()).toBe(true);
+ expect(wrapper.find("button").exists()).toBe(true);
+ });
+
+ it("should hide both controls when showGiveNumbers is true", () => {
+ wrapper = mountComponent({ showGiveNumbers: true });
+
+ expect(wrapper.find('input[type="checkbox"]').exists()).toBe(false);
+ expect(wrapper.find("button").exists()).toBe(false);
+ });
+ });
+
+ describe("Error Handling", () => {
+ it("should handle null props gracefully", () => {
+ wrapper = mountComponent({
+ showGiveNumbers: null as any,
allContactsSelected: null as any,
copyButtonClass: null as any,
- copyButtonDisabled: null as any
- })
- expect(wrapper.exists()).toBe(true)
- })
-
- it('should handle undefined props gracefully', () => {
- wrapper = mountComponent({
- showGiveNumbers: undefined as any,
+ copyButtonDisabled: null as any,
+ });
+ expect(wrapper.exists()).toBe(true);
+ });
+
+ it("should handle undefined props gracefully", () => {
+ wrapper = mountComponent({
+ showGiveNumbers: undefined as any,
allContactsSelected: undefined as any,
copyButtonClass: undefined as any,
- copyButtonDisabled: undefined as any
- })
- expect(wrapper.exists()).toBe(true)
- })
-
- it('should handle malformed props without crashing', () => {
- wrapper = mountComponent({
- showGiveNumbers: 'invalid' as any,
- allContactsSelected: 'invalid' as any,
+ copyButtonDisabled: undefined as any,
+ });
+ expect(wrapper.exists()).toBe(true);
+ });
+
+ it("should handle malformed props without crashing", () => {
+ wrapper = mountComponent({
+ showGiveNumbers: "invalid" as any,
+ allContactsSelected: "invalid" as any,
copyButtonClass: 123 as any,
- copyButtonDisabled: 'invalid' as any
- })
- expect(wrapper.exists()).toBe(true)
- })
-
- it('should handle rapid prop changes without errors', async () => {
- wrapper = mountComponent()
-
+ copyButtonDisabled: "invalid" as any,
+ });
+ expect(wrapper.exists()).toBe(true);
+ });
+
+ it("should handle rapid prop changes without errors", async () => {
+ wrapper = mountComponent();
+
// Rapidly change props
for (let i = 0; i < 10; i++) {
- await wrapper.setProps({
+ await wrapper.setProps({
showGiveNumbers: i % 2 === 0,
allContactsSelected: i % 3 === 0,
copyButtonClass: `class-${i}`,
- copyButtonDisabled: i % 4 === 0
- })
- await wrapper.vm.$nextTick()
+ copyButtonDisabled: i % 4 === 0,
+ });
+ await wrapper.vm.$nextTick();
}
-
- expect(wrapper.exists()).toBe(true)
- })
- })
-
- describe('Performance Testing', () => {
- it('should render within acceptable time', () => {
- const start = performance.now()
- wrapper = mountComponent()
- const end = performance.now()
-
- expect(end - start).toBeLessThan(50) // 50ms threshold
- })
-
- it('should handle rapid prop changes efficiently', async () => {
- wrapper = mountComponent()
- const start = performance.now()
-
+
+ expect(wrapper.exists()).toBe(true);
+ });
+ });
+
+ describe("Performance Testing", () => {
+ it("should render within acceptable time", () => {
+ const start = performance.now();
+ wrapper = mountComponent();
+ const end = performance.now();
+
+ expect(end - start).toBeLessThan(50); // 50ms threshold
+ });
+
+ it("should handle rapid prop changes efficiently", async () => {
+ wrapper = mountComponent();
+ const start = performance.now();
+
// Rapidly change props
for (let i = 0; i < 100; i++) {
- await wrapper.setProps({
+ await wrapper.setProps({
showGiveNumbers: i % 2 === 0,
- allContactsSelected: i % 2 === 0
- })
- await wrapper.vm.$nextTick()
+ allContactsSelected: i % 2 === 0,
+ });
+ await wrapper.vm.$nextTick();
}
-
- const end = performance.now()
- expect(end - start).toBeLessThan(1000) // 1 second threshold
- })
- it('should not cause memory leaks with button interactions', async () => {
+ const end = performance.now();
+ expect(end - start).toBeLessThan(1000); // 1 second threshold
+ });
+
+ it("should not cause memory leaks with button interactions", async () => {
// Create and destroy multiple components
for (let i = 0; i < 50; i++) {
- const tempWrapper = mountComponent()
- const button = tempWrapper.find('button')
- if (button.exists() && !button.attributes('disabled')) {
- await button.trigger('click')
+ const tempWrapper = mountComponent();
+ const button = tempWrapper.find("button");
+ if (button.exists() && !button.attributes("disabled")) {
+ await button.trigger("click");
}
- tempWrapper.unmount()
+ tempWrapper.unmount();
}
-
+
// Force garbage collection if available
if (global.gc) {
- global.gc()
+ global.gc();
}
-
+
// Verify component cleanup
- expect(true).toBe(true)
- })
- })
+ expect(true).toBe(true);
+ });
+ });
- describe('Integration Testing', () => {
- it('should work with parent component context', () => {
+ describe("Integration Testing", () => {
+ it("should work with parent component context", () => {
// Mock parent component
const ParentComponent = {
template: `
@@ -526,171 +533,174 @@ describe('ContactBulkActions', () => {
return {
showGiveNumbers: false,
allContactsSelected: false,
- copyButtonClass: 'btn-primary',
+ copyButtonClass: "btn-primary",
copyButtonDisabled: false,
toggleCalled: false,
- copyCalled: false
- }
+ copyCalled: false,
+ };
},
methods: {
handleToggleAll() {
- (this as any).toggleCalled = true
+ (this as any).toggleCalled = true;
},
handleCopySelected() {
- (this as any).copyCalled = true
- }
- }
- }
-
- const parentWrapper = mount(ParentComponent)
- const bulkActions = parentWrapper.findComponent(ContactBulkActions)
-
- expect(bulkActions.exists()).toBe(true)
- expect((parentWrapper.vm as any).toggleCalled).toBe(false)
- expect((parentWrapper.vm as any).copyCalled).toBe(false)
- })
-
- it('should integrate with contact service', () => {
+ (this as any).copyCalled = true;
+ },
+ },
+ };
+
+ const parentWrapper = mount(ParentComponent);
+ const bulkActions = parentWrapper.findComponent(ContactBulkActions);
+
+ expect(bulkActions.exists()).toBe(true);
+ expect((parentWrapper.vm as any).toggleCalled).toBe(false);
+ expect((parentWrapper.vm as any).copyCalled).toBe(false);
+ });
+
+ it("should integrate with contact service", () => {
// Mock contact service
const contactService = {
getSelectedContacts: vi.fn().mockReturnValue([]),
- toggleAllSelection: vi.fn()
- }
-
+ toggleAllSelection: vi.fn(),
+ };
+
wrapper = mountComponent({
global: {
provide: {
- contactService
- }
- }
- })
-
- expect(wrapper.exists()).toBe(true)
- expect(contactService.getSelectedContacts).not.toHaveBeenCalled()
- })
+ contactService,
+ },
+ },
+ });
+
+ expect(wrapper.exists()).toBe(true);
+ expect(contactService.getSelectedContacts).not.toHaveBeenCalled();
+ });
- it('should work with global properties', () => {
+ it("should work with global properties", () => {
wrapper = mountComponent({
global: {
config: {
globalProperties: {
- $t: (key: string) => key
- }
- }
- }
- })
-
- expect(wrapper.exists()).toBe(true)
- })
- })
-
- describe('Snapshot Testing', () => {
- it('should maintain consistent DOM structure', () => {
- wrapper = mountComponent()
- const html = wrapper.html()
-
+ $t: (key: string) => key,
+ },
+ },
+ },
+ });
+
+ expect(wrapper.exists()).toBe(true);
+ });
+ });
+
+ describe("Snapshot Testing", () => {
+ it("should maintain consistent DOM structure", () => {
+ wrapper = mountComponent();
+ const html = wrapper.html();
+
// Validate specific structure with regex patterns
- expect(html).toMatch(/
]*class="[^"]*mt-2[^"]*"[^>]*>/)
- expect(html).toMatch(/
]*class="[^"]*w-full[^"]*"[^>]*>/)
- expect(html).toMatch(/
]*class="[^"]*text-left[^"]*"[^>]*>/)
- expect(html).toMatch(/
]*type="checkbox"[^>]*>/)
- expect(html).toMatch(/