Ctrl K
ComunidadGuías…

tests/support-links.test.cjs

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
const fs = require('fs');
const path = require('path');
const read = (...p) => fs.readFileSync(path.join(__dirname, '..', ...p), 'utf8');
const assert = (cond, msg) => { if (!cond) throw new Error(msg); };

const PAYPAL = 'https://www.paypal.me/RiDDiX93';
const KOFI = 'https://ko-fi.com/riddix';
const SPONSORS = 'https://github.com/sponsors/RiDDiX';

// GitHub's own Sponsor button on the repo page.
const funding = read('.github', 'FUNDING.yml');
assert(/^github:\s*RiDDiX\s*$/m.test(funding), 'FUNDING.yml must keep the GitHub Sponsors entry');
assert(/^ko_fi:\s*riddix\s*$/m.test(funding), 'FUNDING.yml must expose the Ko-fi account');
assert(funding.includes(PAYPAL), 'FUNDING.yml must expose the PayPal.me link');

// In-app support section (About page).
const about = read('frontend', 'src', 'pages', 'About.tsx');
for (const url of [SPONSORS, PAYPAL, KOFI]) {
  assert(about.includes(url), `About page must link ${url}`);
}
assert(about.includes('rel="noopener noreferrer"') && about.includes('target="_blank"'),
  'external support links must open safely in a new tab');
assert(about.includes('supportTitle'), 'About page must use the localized support heading');

// Localized strings exist (t() falls back to en for other languages).
const i18n = read('frontend', 'src', 'i18n', 'translations.ts');
for (const key of ['supportTitle', 'supportDesc', 'supportGithub', 'supportPaypal', 'supportKofi']) {
  assert(i18n.includes(`${key}:`), `translations must define ${key}`);
}

// README support section.
const readme = read('README.md');
for (const url of [SPONSORS, PAYPAL, KOFI]) {
  assert(readme.includes(url), `README must link ${url}`);
}

// About must be reachable from the UI, not only by typing the URL:
// a permanent sidebar footer link AND the RetroArr wordmark in the header.
const sidebar = read('frontend', 'src', 'components', 'layout', 'Sidebar.tsx');
assert(sidebar.includes('sidebar__footer') && sidebar.includes('sidebar__about'),
  'sidebar needs an always-visible About footer link');
assert(/to="\/about"[\s\S]{0,200}sidebar__logo-btn|sidebar__logo-btn[\s\S]{0,200}RetroArr/.test(sidebar),
  'clicking the RetroArr wordmark must navigate to About');
assert((sidebar.match(/to="\/about"/g) || []).length >= 2,
  'About must be linked from both the brand and the sidebar footer');
// The version/changelog overlay keeps its own trigger (it is not a donation popup).
assert(sidebar.includes('toggleKofi') && sidebar.includes('sidebar__beta'),
  'the version/changelog overlay must keep a trigger of its own');

const app = read('frontend', 'src', 'App.tsx');
assert(app.includes('path="/about"'), '/about route must exist');

// The floating LanguageSwitcher sits fixed at bottom-left over the sidebar, so the
// About footer link has to keep clearance or it gets covered.
const sidebarCss = read('frontend', 'src', 'components', 'layout', 'Sidebar.css');
const footerRule = sidebarCss.match(/\.sidebar__footer\s*\{([^}]*)\}/);
assert(footerRule, '.sidebar__footer rule must exist');
const clearance = footerRule[1].match(/margin-bottom:\s*(\d+)px/);
assert(clearance && Number(clearance[1]) >= 56,
  'sidebar footer needs >=56px bottom clearance for the floating language switcher');

console.log('support-links: all contract checks passed');