Skip to content

test: add unit tests for env validation, middleware CSP, and wallet connectors (closes #935, #936, #937) - #1

Open
freebuff-web[bot] wants to merge 311 commits into
mainfrom
test/eulami-issue-coverage
Open

test: add unit tests for env validation, middleware CSP, and wallet connectors (closes #935, #936, #937)#1
freebuff-web[bot] wants to merge 311 commits into
mainfrom
test/eulami-issue-coverage

Conversation

@freebuff-web

@freebuff-web freebuff-web Bot commented Aug 31, 2026

Copy link
Copy Markdown

Summary

Adds comprehensive unit test coverage for three untested modules assigned to eulami.

Issue MettaChain#935 — Env validation tests

  • src/config/env/__tests__/schema.test.ts — Tests for validateEnv and validateEnvRequirements covering defaults, type coercion, enum validation, and environment-specific requirements.

Issue MettaChain#936 — Middleware CSP tests

  • src/__tests__/middleware.test.ts — Tests for CSP header generation, nonce uniqueness, dev-vs-prod directives, API path skipping, and x-nonce header injection.

Issue MettaChain#937 — Wallet connector tests

  • src/lib/walletConnectors/__tests__/walletConnectors.test.ts — 23 tests covering MetaMask, Coinbase, and WalletConnect adapters (success paths, error cases, availability checks).

Infrastructure

  • Renamed jest.config.jsjest.config.cjs to fix ESM/CJS conflict
  • Removed global WalletConnect mock from jest.setup.js

42 new tests, all passing.

Closes MettaChain#935, Closes MettaChain#936, Closes MettaChain#937

nanaf6203-bit and others added 30 commits June 2, 2026 10:21
WCAG 2.1 improvements to ResponsiveContainer and ResponsiveContainerFluid:

- Add polymorphic �s prop supporting all sectioning/landmark HTML elements
  (main, section, article, aside, header, footer, nav, div) so consumers
  render semantic markup instead of a generic <div>
- Forward aria-label, aria-labelledby, aria-describedby, role, tabIndex,
  onKeyDown and all standard HTMLAttributes to the root element so keyboard
  navigation and screen reader labelling work without extra wrappers
- Add data-testid defaults ('responsive-container' / 'responsive-container-fluid')
  for reliable automated testing
- Export ResponsiveContainerFluidProps interface for type safety

ResponsiveContainerExample.tsx:
- Replace <div>-wrapped header/main/footer with as='header'/'main'/'footer'
- Add aria-label='Primary navigation' to the <nav> element
- Replace bare href='#' links with descriptive href values
- Add aria-labelledby to all <section> containers
- Add aria-hidden='true' to decorative placeholder images

jest.config.js:
- Remove ResponsiveContainer.test.tsx from testPathIgnorePatterns so the
  new a11y test suite runs in CI

Tests (53 tests, all passing):
- Default rendering, data-testid, className merging
- Responsive padding per viewport category (mobile/tablet/desktop/fallback)
- Polymorphic as prop for all 8 supported element types
- ARIA landmark roles accessible via screen reader queries
- aria-label, aria-labelledby, aria-describedby, role forwarding
- Keyboard navigation: tabIndex, onKeyDown, onClick passthrough
- No console.log in production code
- Fluid variant rendering, clamp() padding, ARIA, keyboard
- Edge cases: nested children, sibling containers, unknown attributes

Closes MettaChain#341
Adds 61 focused unit tests for all six components exported from
src/components/responsive/LazyLoadingExample.tsx.

Test coverage per component:

ManualLazyLoadingExample (9 tests)
- setupLazyLoading() called once on mount with the container HTMLDivElement
- setupLazyLoading() not called before mount
- Three images rendered with correct data-src values for lazy loading
- Descriptive alt text on all images (accessibility)
- image-gallery class applied to the container
- 100% width style on all images
- No console.log emitted

PreloadCriticalImagesExample (8 tests)
- preloadCriticalResources() called with exact URL array on mount
- Effect runs only once (not on re-render)
- hero-banner.jpg and featured-property.jpg rendered with src (not data-src)
- Exactly two images rendered
- No console.log emitted

SkeletonImageExample (11 tests)
- property-grid class on wrapper
- Four SkeletonImage loading placeholders rendered (aria-busy=true)
- Skeleton variant has shimmer animation; blur variant has blur filter
- Lazy images use data-src; hero image uses src directly (lazy=false)
- Descriptive alt text on all four images (accessibility)
- No console.log emitted

CustomPlaceholderExample (7 tests)
- ImagePlaceholder shown with aria-label while isLoading=true
- Actual image rendered with opacity 0 while loading
- Placeholder removed and image opacity becomes 1 after onLoad fires
- Multiple load events are idempotent
- No console.log emitted

ContentSkeletonExample (8 tests)
- Skeleton status elements shown initially
- No property content visible before 2000ms timeout
- Content (title, price, description, image) shown after timeout
- Skeletons removed after timeout
- Content does not appear at 1999ms (boundary check)
- No console.log emitted

PropertyListingExample (13 tests)
- preloadCriticalResources called with hero-property.jpg URL
- 12+ skeleton status elements during loading state
- Hero SkeletonImage always visible
- No property titles/prices before 1500ms timeout
- All three properties (titles + prices) appear after 1500ms
- Property cards use lazy loading (data-src set)
- Skeleton cards removed after loading
- Unmounting before timeout does not throw
- No console.log emitted

Edge cases (6 tests)
- setupLazyLoading ref safety on unmount
- Re-mount increments preload call count correctly
- Multiple re-renders do not multiply timeouts
- IntersectionObserver instantiated for lazy images

Closes MettaChain#340
…container-a11y

fix(MettaChain#341): improve accessibility for ResponsiveContainer
…g-example-tests

test(MettaChain#340): add unit tests for LazyLoadingExample
refactor(route-error-boundary): simplify error handling logic
perf(error-test-suite): optimize component rendering performance
- Add useToast hook wrapping sonner with success, error, warning, info, and dismiss methods
- Export hook and ToastOptions type from hooks/index.ts
- Add unit tests for all toast variants
- Leverages existing <Toaster> already mounted in ClientProviders
…ification-system

feat: add global toast notification system (MettaChain#246)
…ttaChain#460) (MettaChain#551)

Inject a synchronous blocking <script> in <head> that reads the
persisted theme from localStorage (matching next-themes storageKey="theme")
and applies the `dark` class on <html> before the first paint. Prevents
the flash of light content for dark-mode users on hard reload, and
keeps CLS at 0 (classList mutations are non-geometric).
suppressHydrationWarning on <html> absorbs the className diff that
next-themes writes again after hydration.
…ger (MettaChain#443) (MettaChain#544)

- Replace Math.random-based sessionId generation with crypto.randomUUID()
- Replace Math.random-based error ID generation with crypto.randomUUID()
- Add structuredLogger tests asserting crypto.randomUUID usage
- Add crypto.randomUUID polyfill to jest.setup.js for jsdom environment
- Remove unpredictable Math.random usage from security-sensitive ID generation

Co-authored-by: akordavid373 <sandrawillow001-afk@users.noreply.github.com>
…MettaChain#447) (MettaChain#545)

- Add verified badge with green shield check icon when on official domain
- Show 'Verified Domain' alert title for canonical domains (propchain.io, localhost)
- Show green-themed verified banner with dismiss option
- Keep existing phishing alert (red) and unofficial warning (yellow) intact
- Add comprehensive test suite for all three banner states

Co-authored-by: akordavid373 <sandrawillow001-afk@users.noreply.github.com>
… helper (MettaChain#441, MettaChain#444) (MettaChain#543)

- Remove hardcoded fallback REVALIDATE_WEBHOOK_SECRET from revalidate route
- Create centralized requireEnv/requireEnvStrict helpers in src/lib/requireEnv.ts
- Add test suite for requireEnv helpers
- requireEnvStrict throws in all environments when env var is missing
- requireEnv provides optional default with dev-only warning

Co-authored-by: akordavid373 <sandrawillow001-afk@users.noreply.github.com>
…aries, DataRefreshWrapper timer cleanup, wallet emoji icons (MettaChain#541)

- MettaChain#429: Add assertValidAddress with EIP-55 checksum validation in walletHelpers.ts
- MettaChain#428: Wrap 7 route pages with withRouteErrorBoundary for graceful error handling
- MettaChain#435: Fix DataRefreshWrapper timer stacking with useRef cleanup + unmount cleanup
- MettaChain#434: Replace emoji wallet icons with lucide-react SVGs and add aria-labels
…ettaChain#439, MettaChain#431 (MettaChain#560)

* fix: resolve 4 assigned a11y and security issues

Issue MettaChain#453 (P1): PropertyCard - remove nested interactive elements
- Replace outer <Link> with <article> to fix nested-interactive violation
- Add explicit <Link> for property title and View button
- Remove stopPropagation calls (no longer needed without parent link)
- Update a11y tests to match new DOM structure

Issue MettaChain#454 (P3): ViewToggle - add accessible names
- Add aria-labels to grid/list buttons for screen-reader support
- Wrap text in <span> for icon-only rendering scenarios

Issue MettaChain#451 (P2): Share URL security
- Create centralized share URL utility with URL validation
- Sanitize display strings to constrained character set
- Use URL constructor to validate all URLs
- Integrate into ShareButton and MortgageCalculator

Issue MettaChain#452 (P2): Global listener leak prevention
- Add cleanup functions for extension event listeners
- Track console overrides for restoration on cleanup
- Create usePerformanceMonitoring hook with lifecycle management

* fix: resolve assigned security issues

- MettaChain#448: deviceId stored unencrypted in localStorage - use per-session in-memory ID
- MettaChain#442: Chainalysis API key exposed via window global - proxy API route
- MettaChain#439: chart.tsx dangerouslySetInnerHTML - sanitize with DOMPurify
- MettaChain#431: batchTransaction confirmation races - viem provider reads + DEMO flag

---------

Co-authored-by: akordavid373 <sandrawillow001-afk@users.noreply.github.com>
…d denylist, audit log rotation (MettaChain#540)

- Create src/middleware.ts with strict CSP headers (default-src 'self', img-src, script-src with nonce)
- Create src/app/api/csp-report/route.ts for CSP violation reports
- Add Playwright E2E test verifying CSP headers block inline scripts
- Add docs/csp.md documenting the policy

- Add memoization per window.location.origin in PhishingProtection.detectPhishing
- Add rate-limited reportPhishing with configurable max reports per minute
- Add clearMemoizedResults for testing
- Add tests for memoization and rate-limiting behavior

- Add loadManifestFromCDN with signed manifest verification
- Keep minimal fallback list (3 domains, 1 contract) for offline scenarios
- Add docs/phishing-denylist.md documenting manifest schema and update procedure
- Add tests for CDN fallback behavior

- Implement LRU-by-time eviction when MAX_LOG_SIZE exceeded
- Add warning at 90% capacity threshold
- Export evicted entries to remote sink before removal
- Add alert rotation with recency-based sorting
- Add docs/audit-retention.md documenting retention policy
- Add tests for eviction, warning, and alert rotation

Co-authored-by: akordavid373 <sandrawillow001-afk@users.noreply.github.com>
Issue MettaChain#453 (P1): PropertyCard - remove nested interactive elements
- Replace outer <Link> with <article> to fix nested-interactive violation
- Add explicit <Link> for property title and View button
- Remove stopPropagation calls (no longer needed without parent link)
- Update a11y tests to match new DOM structure

Issue MettaChain#454 (P3): ViewToggle - add accessible names
- Add aria-labels to grid/list buttons for screen-reader support
- Wrap text in <span> for icon-only rendering scenarios

Issue MettaChain#451 (P2): Share URL security
- Create centralized share URL utility with URL validation
- Sanitize display strings to constrained character set
- Use URL constructor to validate all URLs
- Integrate into ShareButton and MortgageCalculator

Issue MettaChain#452 (P2): Global listener leak prevention
- Add cleanup functions for extension event listeners
- Track console overrides for restoration on cleanup
- Create usePerformanceMonitoring hook with lifecycle management

Co-authored-by: akordavid373 <sandrawillow001-afk@users.noreply.github.com>
…n#459, MettaChain#463, MettaChain#464) (MettaChain#552)

- fix(MettaChain#459): memoize detectInstalledWallets with useMemo to prevent
  re-running wallet detection on every render in WalletModal
- test(MettaChain#463): add comprehensive unit tests for qrCodeSecurity covering
  phishing URL detection, deep-link validation, vbscript protocol,
  allowed hosts matching, edge cases, and getDisplaySafeUrl scenarios
- test(MettaChain#464): add unit tests for useCurrencyConverter covering fetch
  failures, stale data, network reconnect, storage re-hydration,
  conversion functions, auto-refresh interval, and edge cases

closes MettaChain#459
closes MettaChain#463
closes MettaChain#464
…ettaChain#424 - security and code quality improvements (MettaChain#553)

Co-authored-by: JamesEjembi <james@example.com>
…Chain#484, MettaChain#485, MettaChain#486 (MettaChain#607)

* refactor(logger): consolidate logger usage, document canonical logger, migrate consumers (MettaChain#486)

- Add @deprecated JSDoc to src/utils/structuredLogger.ts pointing new code to @/utils/logger.
- Migrate console.* to logger.* in ViewToggle.tsx, TransactionDetailsModal.tsx, errorHandlingTest.ts.
- Migrate @/utils/structuredLogger to @/utils/logger in errorMonitoringService.ts, GlobalErrorBoundary.tsx, LanguageSwitcher.tsx, app/page.tsx (including translation of structured call signatures: info(msg, {metadata}) -> info({...}), error(msg, err, {component,action,metadata}) -> errorWithStack(msg, err, {component,action,...}), component(name, action) -> info(\`Component: ${name} - ${action}\`, ...)).
- Annotate earlyErrorSuppression.ts with a header explaining why it intentionally uses raw console (pre-React intercept of browser-extension noise).
- ESLint enforcement:
  - no-restricted-imports rejects @/utils/structuredLogger (paths/patterns) with a clear migration message.
  - no-console denies direct console.* outside the three logger wrappers and test/story files.
- README § "Logging" documents the canonical logger and the migration story.

Closes MettaChain#486

* perf(next.config): require ANALYZE=true AND non-production for BuildStatsPlugin (MettaChain#485, MettaChain#484)

- Add explicit isProd guard so production builds never run the BuildStatsPlugin even when ANALYZE=true is set (e.g. misconfigured CI).
- README § "Build stats plugin" documents the new gating.

Closes MettaChain#485
Closes MettaChain#484

* refactor(referral): split referralStore into focused slices (MettaChain#483)

- Move create+persist source-of-truth into src/store/referral/store.ts (exposes useReferralStore, ReferralStoreState, ReferralProgramSettings).
- Add focused selector slices under src/store/referral/: referralLinks (useReferralLinks), referralStats (useReferralStats, useRecentRewards), leaderboard (useLeaderboard canonical + useLeaderboardCache alias), referralNotifications (useReferralNotification, useReferralLoading, useReferralError), misc (useCurrentReferralCampaign, useReferralTermsAccepted). Each slice imports from ./store to avoid circular imports.
- Add barrel src/store/referral/index.ts for new code.
- Slim src/store/referralStore.ts to a @deprecated back-compat re-export layer (so existing @/store/referralStore imports and jest mocks keep working).
- Tighten programSettings: any -> ReferralProgramSettings = Record<string, unknown> | null and type initialState explicitly via Pick<ReferralStoreState, ...>.

Closes MettaChain#483
…bility (MettaChain#455) (MettaChain#564)

Replace key={index} with stable composite keys across components
where lists can mutate, improving screen-reader announcements:

- MultiChainPortfolio: use propertyId-fromChain-toChain for bridge suggestions
- WalletModal: use content+index for warning/block messages
- SecureTransactionConfirmation: use content+index for warning/risk messages
- TransactionConfirmation: use content+index for warning/block messages

Closes MettaChain#455
zakariyaufarida5-wq and others added 30 commits August 26, 2026 22:28
…17-csrf-fail-closed

fix(csrf): fail closed when CSRF_SECRET is unset
…18-honest-security-checks

fix(security): replace simulated risk checks with honest unverified results
…tch-checkout

fix(checkout): remove fabricated batch transaction results
…cret-fail-closed

fix(auth): fail closed without JWT secret
…h-wallet-state

fix(auth): derive client state from wallet connection
…orphaned-security-page

fix(security): remove orphaned pages router file
…97-896

Add tests for favoritesStore, certificateStore, walletStore and useDebouncedSearch
…5-894

Add tests for IncomeTracker, transactionSecurityStore, useSafeInfo and usePerformanceMonitoring
…12-910-908

Add tests for PerformanceChart, PortfolioOverview, recentlyViewedStore and paperTradingStore
…-906-905-904

Add tests for onboardingStore, notificationStore, gasPriceStore and developerStore
…1-903-902-899

Add tests for referralStore, comparisonHistoryStore, compare stores and cartStore
…-921-909-893-889

Add tests for PropertyMapView, portfolioStore, pagination hooks and useGestures
…hain#924, MettaChain#925, MettaChain#926, MettaChain#927)

Add Jest specs for DocumentSection and ShareButton (property document
rendering and share flows), TransactionSecuritySettings (security toggle
persistence), and the KYC components (step gating, rejection/retry states,
and audit log rendering).

Also repair the cacheManager test suite so it runs under `npm test`:
- add the missing `defineChain` export to the viem mock, which broke every
  suite that transitively imports viem via chains.ts
- mock ethers' sha256/toUtf8Bytes in cacheManager.test.ts (ethers 6.16
  returns Node Buffers that fail instanceof against the jsdom Uint8Array)
- fix the broken crypto.randomUUID polyfill in jest.setup.js so it emits a
  valid UUID v4, and update a stale sync-queue id assertion

🤖 Generated with Codebuff
Co-Authored-By: Codebuff <noreply@codebuff.com>
Closes MettaChain#934\nCloses MettaChain#935\nCloses MettaChain#936\nCloses MettaChain#937\n\n🤖 Generated with Codebuff\nCo-Authored-By: Codebuff <noreply@codebuff.com>
Completes the batch checkout integration started in MettaChain#960 by wiring a real
wagmi/viem executor. When a batch-purchase contract address is configured,
executeBatchPurchase now resolves the connected wallet client, submits the
batchPurchase call with per-item slippage-protected minimum amounts, and
only reports success after the transaction receipt is observed on chain.

The default path fails closed with a configuration error when no contract
address is set, and disconnected wallets are rejected before any submission.
The timeout/Math.random simulation is not reintroduced anywhere.

Closes MettaChain#813
…al, SetPriceAlertModal

Add unit tests for four previously untested components, closing the
test-coverage issues MettaChain#919, MettaChain#920, MettaChain#922 and MettaChain#923 in the Stellar Wave program.

🤖 Generated with Codebuff
Co-Authored-By: Codebuff <noreply@codebuff.com>
Cover the four untested dashboard components requested in the assigned
issues: RiskAnalysis risk-level derivation and rendering (MettaChain#918),
DiversificationChart allocation derivation including empty and
zero-total inputs (MettaChain#916), PortfolioReport render states and PDF
generation (MettaChain#913), and StakingPanel/StakingModal validation, confirm
gating and success flows (MettaChain#917).

Exports getRiskLevel and computeAllocationPercents so the derivation
logic is directly testable.

Closes MettaChain#913
Closes MettaChain#916
Closes MettaChain#917
Closes MettaChain#918

🤖 Generated with Codebuff
Co-Authored-By: Codebuff <noreply@codebuff.com>
…real-batch-purchase

fix(checkout): submit real batch purchase transaction
…22-923

test: add coverage for RecentTransactions, ImageGallery, PdfViewerModal and SetPriceAlertModal (closes MettaChain#919 MettaChain#920 MettaChain#922 MettaChain#923)
…-component-coverage

test: add coverage for untested dashboard components (RiskAnalysis, DiversificationChart, PortfolioReport, Staking)
…ervices-batch-csrf

test(lib): add coverage for secondary market, portfolio, batch transa…
…onnectors

Add comprehensive test coverage for three untested modules assigned to
eulami (issues MettaChain#935, MettaChain#936, MettaChain#937):

- src/config/env/__tests__/schema.test.ts: Tests for validateEnv and
  validateEnvRequirements covering defaults, type coercion, enum validation,
  and environment-specific requirements (dev/staging/prod).
- src/__tests__/middleware.test.ts: Tests for CSP header generation, nonce
  uniqueness, dev-vs-prod directive differences, API path skipping, and
  x-nonce request header injection.
- src/lib/walletConnectors/__tests__/walletConnectors.test.ts: Tests for
  MetaMask, Coinbase, and WalletConnect adapter mappings covering success
  paths, missing wallet, wrong provider, user rejection, pending request
  errors, and availability checks.

Also renames jest.config.js → jest.config.cjs to fix ESM/CJS conflict
with "type": "module" in package.json, and removes the global
@walletconnect/web3-provider mock from jest.setup.js (now per-test).

Closes MettaChain#935, closes MettaChain#936, closes MettaChain#937

🤖 Generated with Codebuff
Co-Authored-By: Codebuff <noreply@codebuff.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet