Skip to content

Commit da8e99f

Browse files
committed
2899
1 parent aed644b commit da8e99f

1 file changed

Lines changed: 104 additions & 0 deletions

File tree

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
import { describe, it, expect, beforeEach, vi } from 'vitest';
2+
3+
describe('Notification.ts - Responsive Multi-device Columns & Mobile Viewport Layouts', () => {
4+
beforeEach(() => {
5+
// Reset DOM
6+
document.body.innerHTML = '';
7+
8+
// Reset window width mock
9+
Object.defineProperty(window, 'innerWidth', {
10+
writable: true,
11+
configurable: true,
12+
value: 1024,
13+
});
14+
});
15+
16+
it('Mock standard mobile-width media coordinates (e.g. 375px wide viewports)', () => {
17+
// 1. Emulate an exact 375px viewport (mobile standards)
18+
Object.defineProperty(window, 'innerWidth', {
19+
writable: true,
20+
configurable: true,
21+
value: 375,
22+
});
23+
24+
// Wire up matchMedia to respect the simulated mock size
25+
const matchMediaMock = vi.fn().mockImplementation((query) => ({
26+
matches: query === '(max-width: 768px)' ? window.innerWidth <= 768 : false,
27+
media: query,
28+
onchange: null,
29+
addListener: vi.fn(),
30+
removeListener: vi.fn(),
31+
addEventListener: vi.fn(),
32+
removeEventListener: vi.fn(),
33+
dispatchEvent: vi.fn(),
34+
}));
35+
window.matchMedia = matchMediaMock;
36+
37+
expect(window.innerWidth).toBe(375);
38+
expect(window.matchMedia('(max-width: 768px)').matches).toBe(true);
39+
});
40+
41+
it('Assert that columns reflow into standard vertical flex lists', () => {
42+
// 2. Reflowing list structure
43+
const container = document.createElement('div');
44+
45+
// Expected utility classes defining a mobile flex-col flow
46+
// that expands to flex-row natively on larger screens
47+
container.className = 'flex flex-col md:flex-row';
48+
document.body.appendChild(container);
49+
50+
expect(container.classList.contains('flex')).toBe(true);
51+
expect(container.classList.contains('flex-col')).toBe(true);
52+
// Explicitly contains md: breakpoint fallback
53+
expect(container.classList.contains('md:flex-row')).toBe(true);
54+
});
55+
56+
it('Verify styling values are not absolute widths that cause horizontal scrollbars on smaller viewports', () => {
57+
// 3. Validate fluid bounds logic (avoiding horizontal clipping on 375px views)
58+
const notificationCard = document.createElement('div');
59+
60+
// Using percentages or max bounds rather than absolute (e.g. w-[500px])
61+
notificationCard.className = 'w-full max-w-sm rounded-lg';
62+
document.body.appendChild(notificationCard);
63+
64+
// Negative assertion pattern: No illegal fixed width pixel intervals
65+
expect(notificationCard.className).not.toMatch(/w-\[\d+px\]/);
66+
67+
// Positive assertions
68+
expect(notificationCard.classList.contains('w-full')).toBe(true);
69+
expect(notificationCard.classList.contains('max-w-sm')).toBe(true);
70+
});
71+
72+
it('Check that navigation components scale down gracefully', () => {
73+
// 4. Assert navigation elements implement collapsing states mapping to scale priorities
74+
const navItem = document.createElement('span');
75+
navItem.className = 'hidden sm:inline-block text-xs md:text-sm';
76+
document.body.appendChild(navItem);
77+
78+
// By default, strictly 'hidden' on un-prefixed viewport declarations (meaning mobile fallback)
79+
expect(navItem.classList.contains('hidden')).toBe(true);
80+
// Preserves scaling directives for larger text bounds when unlocked
81+
expect(navItem.classList.contains('md:text-sm')).toBe(true);
82+
expect(navItem.classList.contains('text-xs')).toBe(true);
83+
});
84+
85+
it('Assert mobile-specific toggle states respond cleanly', () => {
86+
// 5. Check that touch toggles handle open/close states safely within view constraints
87+
const toggleBtn = document.createElement('button');
88+
let mobileMenuOpen = false;
89+
90+
toggleBtn.addEventListener('click', () => {
91+
mobileMenuOpen = !mobileMenuOpen;
92+
});
93+
94+
document.body.appendChild(toggleBtn);
95+
96+
// Test open execution flow
97+
toggleBtn.dispatchEvent(new MouseEvent('click'));
98+
expect(mobileMenuOpen).toBe(true);
99+
100+
// Test distinct closure cleanup flow
101+
toggleBtn.dispatchEvent(new MouseEvent('click'));
102+
expect(mobileMenuOpen).toBe(false);
103+
});
104+
});

0 commit comments

Comments
 (0)