feat: refine portfolio content, contact, and supporting media

This commit is contained in:
2026-09-05 20:08:57 +03:00
parent 15bcdf7cec
commit 103427f95b
53 changed files with 824 additions and 204 deletions

View File

@@ -0,0 +1,52 @@
import { mount } from '@vue/test-utils';
import { nextTick } from 'vue';
import { afterEach, describe, expect, it, vi } from 'vitest';
import ContactDestination from '@/components/ContactDestination.vue';
import { parsePortfolioContent } from '@/content/schemas';
import content from '@/../content/public/portfolio-content.json';
const contact = parsePortfolioContent(content).contact;
afterEach(() => vi.unstubAllGlobals());
describe('contact disclosure', () => {
it('assembles a mail link only after pointer or keyboard interaction', async () => {
const wrapper = mount(ContactDestination, { props: { contact } });
await nextTick();
expect(wrapper.find('a[href^="mailto:"]').exists()).toBe(false);
expect(wrapper.get('.contact-email__preview').text()).toBe('');
await wrapper.get('.contact-email__action').trigger('focusin');
expect(wrapper.get('a.contact-link').attributes('href')).toBe('mailto:luca.pislaru@gmail.com');
expect(wrapper.get('a.contact-link').text()).toBe('Email Me');
wrapper.unmount();
});
it('reveals a copyable address through the native disclosure', async () => {
const writeText = vi.fn().mockResolvedValue(undefined);
vi.stubGlobal('navigator', { clipboard: { writeText } });
const wrapper = mount(ContactDestination, { props: { contact } });
await nextTick();
const details = wrapper.get('details');
(details.element as HTMLDetailsElement).open = true;
await details.trigger('toggle');
expect(wrapper.get('summary').text()).toBe('Hide email');
expect(wrapper.get('.contact-email__address').text()).toBe('luca.pislaru@gmail.com');
await wrapper.get('.contact-email__copy').trigger('click');
expect(writeText).toHaveBeenCalledWith('luca.pislaru@gmail.com');
expect(wrapper.get('[role="status"]').text()).toBe('Copied');
await wrapper.get('.contact-email').trigger('keydown', { key: 'Escape' });
expect((details.element as HTMLDetailsElement).open).toBe(false);
wrapper.unmount();
});
it('keeps the address selectable when clipboard permission is unavailable', async () => {
vi.stubGlobal('navigator', { clipboard: { writeText: vi.fn().mockRejectedValue(new Error('Unavailable')) } });
const wrapper = mount(ContactDestination, { props: { contact } });
await nextTick();
(wrapper.get('details').element as HTMLDetailsElement).open = true;
await wrapper.get('details').trigger('toggle');
await wrapper.get('.contact-email__copy').trigger('click');
expect(wrapper.get('[role="status"]').text()).toBe('Select the address to copy it.');
expect(wrapper.get('.contact-email__address').text()).toContain('@');
wrapper.unmount();
});
});