@thorprovider/blocks 0.1.3 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +155 -0
- package/README.md +228 -68
- package/docs/standards/data-contracts.md +13 -2
- package/package.json +26 -10
- package/scripts/fix-esm-extensions.mjs +40 -0
- package/src/blocks/application/login-forms/login-page.test.tsx +190 -0
- package/src/blocks/application/login-forms/login-page.tsx +240 -0
- package/src/blocks/application/password-recovery/forgot-password-page-1.tsx +6 -8
- package/src/blocks/application/signup-forms/signup-page-1.tsx +127 -129
- package/src/blocks/application/verification/verify-1.tsx +2 -2
- package/src/blocks/application/viewport-ownership.test.tsx +41 -0
- package/src/blocks/e-commerce/category-filters/category-listing-filter-fields.tsx +218 -0
- package/src/blocks/e-commerce/category-filters/{category-filter-2.test.tsx → category-listing.test.tsx} +287 -199
- package/src/blocks/e-commerce/category-filters/category-listing.tsx +934 -0
- package/src/blocks/e-commerce/checkout-forms/checkout-contact-step.tsx +149 -0
- package/src/blocks/e-commerce/checkout-forms/{checkout-form-1-country-field.tsx → checkout-country-field.tsx} +10 -8
- package/src/blocks/e-commerce/checkout-forms/checkout-order-summary.tsx +230 -0
- package/src/blocks/e-commerce/checkout-forms/checkout-payment-step.tsx +100 -0
- package/src/blocks/e-commerce/checkout-forms/checkout-progress.tsx +62 -0
- package/src/blocks/e-commerce/checkout-forms/checkout-review-step.tsx +59 -0
- package/src/blocks/e-commerce/checkout-forms/{checkout-form-1-shipping-step.tsx → checkout-shipping-step.tsx} +65 -41
- package/src/blocks/e-commerce/checkout-forms/checkout.test.tsx +478 -0
- package/src/blocks/e-commerce/checkout-forms/checkout.tsx +550 -0
- package/src/blocks/e-commerce/navigation/storefront-navbar-account-menu.test.tsx +56 -0
- package/src/blocks/{marketing/navbars/navbar-4-account-menu.tsx → e-commerce/navigation/storefront-navbar-account-menu.tsx} +3 -3
- package/src/blocks/{marketing/navbars/navbar-4-cart-sheet.test.tsx → e-commerce/navigation/storefront-navbar-cart-sheet.test.tsx} +22 -22
- package/src/blocks/{marketing/navbars/navbar-4-cart-sheet.tsx → e-commerce/navigation/storefront-navbar-cart-sheet.tsx} +3 -3
- package/src/blocks/{marketing/navbars/navbar-4-mobile-nav.tsx → e-commerce/navigation/storefront-navbar-mobile-nav.tsx} +4 -12
- package/src/blocks/{marketing/navbars/navbar-4-search-bar.tsx → e-commerce/navigation/storefront-navbar-search-bar.tsx} +3 -3
- package/src/blocks/{marketing/navbars/navbar-4.test.tsx → e-commerce/navigation/storefront-navbar.test.tsx} +67 -36
- package/src/blocks/{marketing/navbars/navbar-4.tsx → e-commerce/navigation/storefront-navbar.tsx} +43 -25
- package/src/blocks/e-commerce/product-categories/category-card-grid.test.tsx +122 -0
- package/src/blocks/e-commerce/product-categories/category-card.test.tsx +68 -0
- package/src/blocks/e-commerce/product-categories/category-card.tsx +172 -0
- package/src/blocks/e-commerce/product-categories/category-grid.test.tsx +67 -0
- package/src/blocks/e-commerce/product-categories/category-shared.tsx +109 -0
- package/src/blocks/e-commerce/product-categories/product-category-grid.tsx +170 -0
- package/src/blocks/e-commerce/product-categories/product-category.test.tsx +266 -0
- package/src/blocks/e-commerce/product-categories/product-category.tsx +462 -0
- package/src/blocks/e-commerce/product-list/product-card.test.tsx +263 -0
- package/src/blocks/e-commerce/product-list/product-card.tsx +447 -0
- package/src/blocks/e-commerce/product-list/product-grid.test.tsx +162 -0
- package/src/blocks/e-commerce/product-list/product-grid.tsx +114 -0
- package/src/blocks/e-commerce/product-overview/product-overview-gallery.tsx +71 -0
- package/src/blocks/e-commerce/product-overview/{product-overview-5-lightbox-tab.tsx → product-overview-lightbox-tab.tsx} +35 -23
- package/src/blocks/e-commerce/product-overview/{product-overview-5-reviews-tab.tsx → product-overview-reviews-tab.tsx} +40 -17
- package/src/blocks/e-commerce/product-overview/{product-overview-5-tabs.tsx → product-overview-tabs.tsx} +8 -7
- package/src/blocks/e-commerce/product-overview/product-overview.test.tsx +283 -0
- package/src/blocks/e-commerce/product-overview/product-overview.tsx +1186 -0
- package/src/blocks/e-commerce/reviews/review-rating-2.tsx +5 -6
- package/src/blocks/e-commerce/shopping-carts/shopping-cart.test.tsx +399 -0
- package/src/blocks/e-commerce/shopping-carts/{shopping-cart-4.tsx → shopping-cart.tsx} +119 -85
- package/src/blocks/e-commerce/storefront-hero/storefront-hero.test.tsx +412 -0
- package/src/blocks/e-commerce/storefront-hero/storefront-hero.tsx +1283 -0
- package/src/blocks/marketing/features/feature.test.tsx +153 -0
- package/src/blocks/marketing/features/feature.tsx +195 -0
- package/src/blocks/marketing/footers/footer-section-accessibility.test.tsx +118 -0
- package/src/blocks/marketing/footers/footer-section-actions.test.tsx +131 -0
- package/src/blocks/marketing/footers/footer-section-data.test.tsx +127 -0
- package/src/blocks/marketing/footers/footer-section-native-links.test.tsx +100 -0
- package/src/blocks/marketing/footers/footer-section-public-api.test.tsx +11 -0
- package/src/blocks/marketing/footers/footer-section.test.tsx +46 -0
- package/src/blocks/marketing/footers/footer-section.tsx +532 -0
- package/src/blocks/marketing/navbars/navbar-public-api.test.tsx +57 -0
- package/src/blocks/marketing/navbars/navbar.mega.test.tsx +149 -0
- package/src/blocks/marketing/navbars/navbar.test.tsx +155 -0
- package/src/blocks/marketing/navbars/navbar.tsx +735 -0
- package/src/blocks/marketing/testimonials/testimonial-section.test.tsx +171 -0
- package/src/blocks/marketing/testimonials/testimonial-section.tsx +237 -0
- package/src/index.ts +156 -128
- package/src/lib/contracts-curated.test.ts +47 -29
- package/src/lib/contracts.test.ts +198 -2
- package/src/lib/contracts.ts +410 -16
- package/src/ui/button-group.tsx +1 -1
- package/src/ui/carousel.tsx +1 -1
- package/src/ui/dialog.tsx +1 -1
- package/src/ui/field.tsx +2 -2
- package/src/ui/input-group.tsx +3 -3
- package/src/ui/pagination.tsx +1 -1
- package/src/ui/sidebar.tsx +7 -7
- package/src/ui/toggle-group.tsx +1 -1
- package/tsconfig.build.json +12 -0
- package/tsup.config.ts +11 -7
- package/.turbo/turbo-build.log +0 -24
- package/.turbo/turbo-test.log +0 -47
- package/.turbo/turbo-type-check.log +0 -0
- package/dist/.tsbuildinfo +0 -1
- package/dist/contracts.d.mts +0 -1732
- package/dist/contracts.d.ts +0 -1732
- package/dist/contracts.js +0 -423
- package/dist/contracts.js.map +0 -1
- package/dist/contracts.mjs +0 -365
- package/dist/contracts.mjs.map +0 -1
- package/dist/index.d.mts +0 -3068
- package/dist/index.d.ts +0 -3068
- package/dist/index.js +0 -17834
- package/dist/index.js.map +0 -1
- package/dist/index.mjs +0 -17740
- package/dist/index.mjs.map +0 -1
- package/src/blocks/application/login-forms/login-page-1.tsx +0 -246
- package/src/blocks/application/login-forms/login-page-2.tsx +0 -207
- package/src/blocks/e-commerce/category-filters/category-filter-1.tsx +0 -260
- package/src/blocks/e-commerce/category-filters/category-filter-2-filter-panel.tsx +0 -222
- package/src/blocks/e-commerce/category-filters/category-filter-2.tsx +0 -921
- package/src/blocks/e-commerce/category-filters/category-filter-4-chip-rail.tsx +0 -57
- package/src/blocks/e-commerce/category-filters/category-filter-4-drawer.tsx +0 -124
- package/src/blocks/e-commerce/category-filters/category-filter-4-fields.tsx +0 -170
- package/src/blocks/e-commerce/category-filters/category-filter-4-sidebar.tsx +0 -52
- package/src/blocks/e-commerce/category-filters/category-filter-4-sort-sheet.tsx +0 -57
- package/src/blocks/e-commerce/category-filters/category-filter-4-state.ts +0 -68
- package/src/blocks/e-commerce/category-filters/category-filter-4.tsx +0 -298
- package/src/blocks/e-commerce/checkout-forms/card-formatting.test.ts +0 -47
- package/src/blocks/e-commerce/checkout-forms/card-formatting.ts +0 -9
- package/src/blocks/e-commerce/checkout-forms/checkout-form-1-contact-step.tsx +0 -96
- package/src/blocks/e-commerce/checkout-forms/checkout-form-1-order-summary.tsx +0 -252
- package/src/blocks/e-commerce/checkout-forms/checkout-form-1-payment-step.tsx +0 -188
- package/src/blocks/e-commerce/checkout-forms/checkout-form-1-progress.tsx +0 -36
- package/src/blocks/e-commerce/checkout-forms/checkout-form-1.test.tsx +0 -216
- package/src/blocks/e-commerce/checkout-forms/checkout-form-1.tsx +0 -338
- package/src/blocks/e-commerce/checkout-forms/checkout-form-2-order-summary.tsx +0 -130
- package/src/blocks/e-commerce/checkout-forms/checkout-form-2-payment-card.tsx +0 -175
- package/src/blocks/e-commerce/checkout-forms/checkout-form-2-shipping-card.tsx +0 -190
- package/src/blocks/e-commerce/checkout-forms/checkout-form-2.tsx +0 -312
- package/src/blocks/e-commerce/checkout-forms/checkout-form-3-information-step.tsx +0 -91
- package/src/blocks/e-commerce/checkout-forms/checkout-form-3-order-summary.tsx +0 -110
- package/src/blocks/e-commerce/checkout-forms/checkout-form-3-payment-step.tsx +0 -137
- package/src/blocks/e-commerce/checkout-forms/checkout-form-3-progress.tsx +0 -68
- package/src/blocks/e-commerce/checkout-forms/checkout-form-3-review-step.tsx +0 -79
- package/src/blocks/e-commerce/checkout-forms/checkout-form-3-shipping-step.tsx +0 -172
- package/src/blocks/e-commerce/checkout-forms/checkout-form-3.tsx +0 -392
- package/src/blocks/e-commerce/product-categories/avatar-group.tsx +0 -86
- package/src/blocks/e-commerce/product-categories/product-category-1.tsx +0 -126
- package/src/blocks/e-commerce/product-categories/product-category-2.test.tsx +0 -51
- package/src/blocks/e-commerce/product-categories/product-category-2.tsx +0 -120
- package/src/blocks/e-commerce/product-categories/product-category-4.tsx +0 -129
- package/src/blocks/e-commerce/product-categories/product-category-5.tsx +0 -218
- package/src/blocks/e-commerce/product-list/product-card-1.test.tsx +0 -88
- package/src/blocks/e-commerce/product-list/product-card-1.tsx +0 -192
- package/src/blocks/e-commerce/product-list/product-card-2.tsx +0 -71
- package/src/blocks/e-commerce/product-list/product-card-3-reaction-toggle.tsx +0 -166
- package/src/blocks/e-commerce/product-list/product-card-3.tsx +0 -215
- package/src/blocks/e-commerce/product-list/product-card-5-checkbox-check.tsx +0 -98
- package/src/blocks/e-commerce/product-list/product-card-5-reaction-toggle.tsx +0 -171
- package/src/blocks/e-commerce/product-list/product-card-5.tsx +0 -367
- package/src/blocks/e-commerce/product-overview/product-overview-1.test.tsx +0 -182
- package/src/blocks/e-commerce/product-overview/product-overview-1.tsx +0 -370
- package/src/blocks/e-commerce/product-overview/product-overview-2.tsx +0 -272
- package/src/blocks/e-commerce/product-overview/product-overview-5-gallery.tsx +0 -59
- package/src/blocks/e-commerce/product-overview/product-overview-5.tsx +0 -274
- package/src/blocks/e-commerce/shopping-carts/shopping-cart-1-spinning-counter.tsx +0 -142
- package/src/blocks/e-commerce/shopping-carts/shopping-cart-1.tsx +0 -291
- package/src/blocks/e-commerce/shopping-carts/shopping-cart-2-item-row.tsx +0 -110
- package/src/blocks/e-commerce/shopping-carts/shopping-cart-2-recommendations.tsx +0 -51
- package/src/blocks/e-commerce/shopping-carts/shopping-cart-2-spinning-counter.tsx +0 -146
- package/src/blocks/e-commerce/shopping-carts/shopping-cart-2.tsx +0 -295
- package/src/blocks/e-commerce/shopping-carts/shopping-cart-3-spinning-counter.tsx +0 -142
- package/src/blocks/e-commerce/shopping-carts/shopping-cart-3.tsx +0 -342
- package/src/blocks/e-commerce/shopping-carts/shopping-cart-4-spinning-counter.tsx +0 -146
- package/src/blocks/e-commerce/shopping-carts/shopping-cart-4.test.tsx +0 -229
- package/src/blocks/e-commerce/storefront-hero/storefront-hero-1.test.tsx +0 -72
- package/src/blocks/e-commerce/storefront-hero/storefront-hero-1.tsx +0 -263
- package/src/blocks/e-commerce/storefront-hero/storefront-hero-2.tsx +0 -283
- package/src/blocks/e-commerce/storefront-hero/storefront-hero-5.tsx +0 -318
- package/src/blocks/e-commerce/storefront-hero/storefront-hero-6.tsx +0 -205
- package/src/blocks/marketing/features/feature-1.tsx +0 -97
- package/src/blocks/marketing/features/feature-2.tsx +0 -82
- package/src/blocks/marketing/footers/footer-section-1.test.tsx +0 -117
- package/src/blocks/marketing/footers/footer-section-1.tsx +0 -178
- package/src/blocks/marketing/footers/footer-section-3.tsx +0 -192
- package/src/blocks/marketing/footers/footer-section-4.tsx +0 -355
- package/src/blocks/marketing/navbars/navbar-1.tsx +0 -267
- package/src/blocks/marketing/navbars/navbar-2.tsx +0 -351
- package/src/blocks/marketing/navbars/navbar-3.tsx +0 -303
- package/src/blocks/marketing/navbars/navbar-4-account-menu.test.tsx +0 -38
- package/src/blocks/marketing/navbars/navbar-4-like-button.tsx +0 -177
- package/src/blocks/marketing/navbars/navbar-4-product-grid.tsx +0 -219
- package/src/blocks/marketing/testimonials/testimonial-1.tsx +0 -141
- package/src/blocks/marketing/testimonials/testimonial-2.tsx +0 -108
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
// @vitest-environment jsdom
|
|
2
|
+
import { fireEvent, render, screen } from '@testing-library/react'
|
|
3
|
+
import { AtSign } from 'lucide-react'
|
|
4
|
+
import { describe, expect, it, vi } from 'vitest'
|
|
5
|
+
|
|
6
|
+
import {
|
|
7
|
+
FooterSection,
|
|
8
|
+
type FooterSectionProps,
|
|
9
|
+
type FooterSocialLink,
|
|
10
|
+
} from './footer-section'
|
|
11
|
+
|
|
12
|
+
const baseProps = {
|
|
13
|
+
presentation: 'contact',
|
|
14
|
+
brandName: 'Thor Provider',
|
|
15
|
+
linkColumns: [],
|
|
16
|
+
} satisfies FooterSectionProps
|
|
17
|
+
|
|
18
|
+
const instagram = {
|
|
19
|
+
label: 'Instagram',
|
|
20
|
+
href: '/redes/instagram',
|
|
21
|
+
icon: 'instagram',
|
|
22
|
+
} satisfies FooterSocialLink
|
|
23
|
+
|
|
24
|
+
describe('FooterSection serializable social content and list identities', () => {
|
|
25
|
+
it('round-trips social identifiers as plain JSON data', () => {
|
|
26
|
+
const serialized = JSON.stringify([instagram])
|
|
27
|
+
|
|
28
|
+
expect(serialized).toBe(
|
|
29
|
+
'[{"label":"Instagram","href":"/redes/instagram","icon":"instagram"}]',
|
|
30
|
+
)
|
|
31
|
+
expect(JSON.parse(serialized)).toEqual([instagram])
|
|
32
|
+
})
|
|
33
|
+
|
|
34
|
+
it('renders a host-bound icon for its serializable identifier', () => {
|
|
35
|
+
render(
|
|
36
|
+
<FooterSection
|
|
37
|
+
{...baseProps}
|
|
38
|
+
socialLinks={[instagram]}
|
|
39
|
+
socialIcons={{ instagram: AtSign }}
|
|
40
|
+
onSocialClick={() => undefined}
|
|
41
|
+
/>,
|
|
42
|
+
)
|
|
43
|
+
|
|
44
|
+
const socialLink = screen.getByRole('link', { name: 'Instagram' })
|
|
45
|
+
expect(socialLink.getAttribute('href')).toBe('/redes/instagram')
|
|
46
|
+
expect(socialLink.querySelector('svg')).not.toBeNull()
|
|
47
|
+
})
|
|
48
|
+
|
|
49
|
+
it('uses an optional accessible name without changing the raw social label', () => {
|
|
50
|
+
const onSocialClick = vi.fn()
|
|
51
|
+
const socialLink = { ...instagram, ariaLabel: 'Seguir en Instagram' }
|
|
52
|
+
|
|
53
|
+
render(
|
|
54
|
+
<FooterSection
|
|
55
|
+
{...baseProps}
|
|
56
|
+
socialLinks={[socialLink]}
|
|
57
|
+
socialIcons={{ instagram: AtSign }}
|
|
58
|
+
onSocialClick={onSocialClick}
|
|
59
|
+
/>,
|
|
60
|
+
)
|
|
61
|
+
|
|
62
|
+
const control = screen.getByRole('link', { name: 'Seguir en Instagram' })
|
|
63
|
+
expect(control.textContent).toContain('Instagram')
|
|
64
|
+
fireEvent.click(control)
|
|
65
|
+
expect(onSocialClick).toHaveBeenCalledWith('Instagram')
|
|
66
|
+
})
|
|
67
|
+
|
|
68
|
+
it('keeps the provider label visible when its icon identifier is unmapped', () => {
|
|
69
|
+
render(
|
|
70
|
+
<FooterSection
|
|
71
|
+
{...baseProps}
|
|
72
|
+
socialLinks={[instagram]}
|
|
73
|
+
socialIcons={{}}
|
|
74
|
+
onSocialClick={() => undefined}
|
|
75
|
+
/>,
|
|
76
|
+
)
|
|
77
|
+
|
|
78
|
+
const socialLink = screen.getByRole('link', { name: 'Instagram' })
|
|
79
|
+
expect(socialLink.textContent).toContain('Instagram')
|
|
80
|
+
expect(socialLink.querySelector('svg')).toBeNull()
|
|
81
|
+
})
|
|
82
|
+
|
|
83
|
+
it('rejects duplicate column identities instead of emitting duplicate keys', () => {
|
|
84
|
+
expect(() =>
|
|
85
|
+
render(
|
|
86
|
+
<FooterSection
|
|
87
|
+
{...baseProps}
|
|
88
|
+
linkColumns={[
|
|
89
|
+
{ title: 'Servicios', links: [{ label: 'Talleres' }] },
|
|
90
|
+
{ title: 'Servicios', links: [{ label: 'Repuestos' }] },
|
|
91
|
+
]}
|
|
92
|
+
/>,
|
|
93
|
+
),
|
|
94
|
+
).toThrow(/column.*keys must be unique/i)
|
|
95
|
+
})
|
|
96
|
+
|
|
97
|
+
it('rejects duplicate link identities within a column', () => {
|
|
98
|
+
expect(() =>
|
|
99
|
+
render(
|
|
100
|
+
<FooterSection
|
|
101
|
+
{...baseProps}
|
|
102
|
+
linkColumns={[
|
|
103
|
+
{
|
|
104
|
+
title: 'Servicios',
|
|
105
|
+
links: [
|
|
106
|
+
{ label: 'Talleres', href: '/talleres' },
|
|
107
|
+
{ label: 'Talleres', href: '/talleres' },
|
|
108
|
+
],
|
|
109
|
+
},
|
|
110
|
+
]}
|
|
111
|
+
/>,
|
|
112
|
+
),
|
|
113
|
+
).toThrow(/link.*keys must be unique/i)
|
|
114
|
+
})
|
|
115
|
+
|
|
116
|
+
it('rejects duplicate social identities instead of emitting duplicate keys', () => {
|
|
117
|
+
expect(() =>
|
|
118
|
+
render(
|
|
119
|
+
<FooterSection
|
|
120
|
+
{...baseProps}
|
|
121
|
+
socialLinks={[instagram, instagram]}
|
|
122
|
+
onSocialClick={() => undefined}
|
|
123
|
+
/>,
|
|
124
|
+
),
|
|
125
|
+
).toThrow(/social.*keys must be unique/i)
|
|
126
|
+
})
|
|
127
|
+
})
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
// @vitest-environment jsdom
|
|
2
|
+
import { render, screen } from '@testing-library/react'
|
|
3
|
+
import { AtSign } from 'lucide-react'
|
|
4
|
+
import { describe, expect, it, vi } from 'vitest'
|
|
5
|
+
|
|
6
|
+
import { FooterSection, type FooterSectionProps } from './footer-section'
|
|
7
|
+
|
|
8
|
+
const nativeProps = {
|
|
9
|
+
presentation: 'brand-columns',
|
|
10
|
+
linkBehavior: 'native',
|
|
11
|
+
brandName: 'Thor Provider',
|
|
12
|
+
linkColumns: [
|
|
13
|
+
{
|
|
14
|
+
title: 'Repuestos',
|
|
15
|
+
links: [{ label: 'Catálogo de repuestos', href: '/repuestos' }],
|
|
16
|
+
},
|
|
17
|
+
],
|
|
18
|
+
socialLinks: [
|
|
19
|
+
{ label: 'Instagram', href: '/redes/instagram', icon: 'instagram' },
|
|
20
|
+
],
|
|
21
|
+
socialIcons: { instagram: AtSign },
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
describe('FooterSection native link compatibility', () => {
|
|
25
|
+
it('keeps native column hrefs separate from host-controlled social links', () => {
|
|
26
|
+
render(
|
|
27
|
+
<FooterSection
|
|
28
|
+
{...(nativeProps as unknown as FooterSectionProps)}
|
|
29
|
+
/>,
|
|
30
|
+
)
|
|
31
|
+
|
|
32
|
+
expect(
|
|
33
|
+
screen
|
|
34
|
+
.getByRole('link', { name: 'Catálogo de repuestos' })
|
|
35
|
+
.getAttribute('href'),
|
|
36
|
+
).toBe('/repuestos')
|
|
37
|
+
expect(screen.getByText('Instagram').closest('a')).toBeNull()
|
|
38
|
+
})
|
|
39
|
+
|
|
40
|
+
it('notifies native column callbacks without preventing browser navigation', () => {
|
|
41
|
+
const onLinkClick = vi.fn()
|
|
42
|
+
const props = {
|
|
43
|
+
...nativeProps,
|
|
44
|
+
onLinkClick,
|
|
45
|
+
} as unknown as FooterSectionProps
|
|
46
|
+
|
|
47
|
+
render(<FooterSection {...props} />)
|
|
48
|
+
|
|
49
|
+
const columnLink = screen.getByRole('link', {
|
|
50
|
+
name: 'Catálogo de repuestos',
|
|
51
|
+
})
|
|
52
|
+
const columnEvent = new MouseEvent('click', {
|
|
53
|
+
bubbles: true,
|
|
54
|
+
cancelable: true,
|
|
55
|
+
})
|
|
56
|
+
columnLink.dispatchEvent(columnEvent)
|
|
57
|
+
|
|
58
|
+
expect(onLinkClick).toHaveBeenCalledWith(
|
|
59
|
+
nativeProps.linkColumns[0]?.links[0],
|
|
60
|
+
)
|
|
61
|
+
expect(columnEvent.defaultPrevented).toBe(false)
|
|
62
|
+
expect(screen.getByText('Instagram').closest('a')).toBeNull()
|
|
63
|
+
})
|
|
64
|
+
|
|
65
|
+
it('keeps native social hrefs separate from host-controlled column links', () => {
|
|
66
|
+
const props = {
|
|
67
|
+
...nativeProps,
|
|
68
|
+
linkBehavior: 'host',
|
|
69
|
+
socialLinkBehavior: 'native',
|
|
70
|
+
} as unknown as FooterSectionProps
|
|
71
|
+
|
|
72
|
+
render(<FooterSection {...props} />)
|
|
73
|
+
|
|
74
|
+
expect(screen.getByText('Catálogo de repuestos').closest('a')).toBeNull()
|
|
75
|
+
const socialLink = screen.getByRole('link', { name: 'Instagram' })
|
|
76
|
+
expect(socialLink.getAttribute('href')).toBe('/redes/instagram')
|
|
77
|
+
})
|
|
78
|
+
|
|
79
|
+
it('notifies native social callbacks without preventing browser navigation', () => {
|
|
80
|
+
const onSocialClick = vi.fn()
|
|
81
|
+
const props = {
|
|
82
|
+
...nativeProps,
|
|
83
|
+
linkBehavior: 'host',
|
|
84
|
+
socialLinkBehavior: 'native',
|
|
85
|
+
onSocialClick,
|
|
86
|
+
} as unknown as FooterSectionProps
|
|
87
|
+
|
|
88
|
+
render(<FooterSection {...props} />)
|
|
89
|
+
|
|
90
|
+
const socialLink = screen.getByRole('link', { name: 'Instagram' })
|
|
91
|
+
const socialEvent = new MouseEvent('click', {
|
|
92
|
+
bubbles: true,
|
|
93
|
+
cancelable: true,
|
|
94
|
+
})
|
|
95
|
+
socialLink.dispatchEvent(socialEvent)
|
|
96
|
+
|
|
97
|
+
expect(onSocialClick).toHaveBeenCalledWith('Instagram')
|
|
98
|
+
expect(socialEvent.defaultPrevented).toBe(false)
|
|
99
|
+
})
|
|
100
|
+
})
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { describe, expect, it } from 'vitest'
|
|
2
|
+
import * as blockExports from '../../../index'
|
|
3
|
+
|
|
4
|
+
describe('Blocks footer package exports', () => {
|
|
5
|
+
it('exposes the canonical footer and omits retired numbered adapters', () => {
|
|
6
|
+
expect(blockExports.FooterSection).toEqual(expect.any(Function))
|
|
7
|
+
expect('FooterSection1' in blockExports).toBe(false)
|
|
8
|
+
expect('FooterSection3' in blockExports).toBe(false)
|
|
9
|
+
expect('FooterSection4' in blockExports).toBe(false)
|
|
10
|
+
})
|
|
11
|
+
})
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
// @vitest-environment jsdom
|
|
2
|
+
import { render, screen } from '@testing-library/react'
|
|
3
|
+
import { describe, expect, it } from 'vitest'
|
|
4
|
+
|
|
5
|
+
import { FooterSection, type FooterSectionProps } from './footer-section'
|
|
6
|
+
|
|
7
|
+
const presentations = ['brand-columns', 'newsletter-grid', 'contact'] as const
|
|
8
|
+
|
|
9
|
+
const sharedProps = {
|
|
10
|
+
brandName: 'Thor Provider',
|
|
11
|
+
brandDescription: 'Repuestos y soluciones para talleres.',
|
|
12
|
+
linkColumns: [
|
|
13
|
+
{
|
|
14
|
+
title: 'Repuestos',
|
|
15
|
+
links: [{ label: 'Catálogo de repuestos', href: '/repuestos' }],
|
|
16
|
+
},
|
|
17
|
+
],
|
|
18
|
+
copyright: '© 2026 Thor Provider',
|
|
19
|
+
} satisfies Omit<FooterSectionProps, 'presentation'>
|
|
20
|
+
|
|
21
|
+
describe('FooterSection', () => {
|
|
22
|
+
it('rejects a missing presentation instead of silently choosing a layout', () => {
|
|
23
|
+
expect(() =>
|
|
24
|
+
render(
|
|
25
|
+
<FooterSection
|
|
26
|
+
{...sharedProps}
|
|
27
|
+
presentation={undefined as unknown as FooterSectionProps['presentation']}
|
|
28
|
+
/>,
|
|
29
|
+
),
|
|
30
|
+
).toThrow(/presentation/i)
|
|
31
|
+
})
|
|
32
|
+
|
|
33
|
+
it.each(presentations)(
|
|
34
|
+
'renders the shared page-level footer responsibilities for %s',
|
|
35
|
+
(presentation) => {
|
|
36
|
+
render(<FooterSection {...sharedProps} presentation={presentation} />)
|
|
37
|
+
|
|
38
|
+
expect(screen.getByRole('contentinfo')).toBeTruthy()
|
|
39
|
+
expect(screen.getByText('Thor Provider')).toBeTruthy()
|
|
40
|
+
expect(screen.getByText('Repuestos y soluciones para talleres.')).toBeTruthy()
|
|
41
|
+
expect(screen.getByText('Repuestos')).toBeTruthy()
|
|
42
|
+
expect(screen.getByText('Catálogo de repuestos')).toBeTruthy()
|
|
43
|
+
expect(screen.getByText('© 2026 Thor Provider')).toBeTruthy()
|
|
44
|
+
},
|
|
45
|
+
)
|
|
46
|
+
})
|