feat: partners section on the homepage (logo + URL, CMS upload)
CI Pipeline with Test Management / 🧪 Run Tests & Generate Reports (push) Waiting to run
CI Pipeline with Test Management / 🐳 Docker Integration Tests (push) Blocked by required conditions
CI Pipeline with Test Management / 🏗️ Build Docker Image (push) Blocked by required conditions
CI Pipeline with Test Management / 📊 Generate Test Summary (push) Blocked by required conditions
Test Reporting & Gherkin Analysis / 🧪 Run Tests & Generate Reports (push) Waiting to run
Test Reporting & Gherkin Analysis / 📊 Analyze Test Coverage (push) Blocked by required conditions
Test Reporting & Gherkin Analysis / 🔄 Sync with Linear (push) Blocked by required conditions
Test Reporting & Gherkin Analysis / ⚡ Performance Monitoring (push) Blocked by required conditions
CI Pipeline with Test Management / 🧪 Run Tests & Generate Reports (push) Waiting to run
CI Pipeline with Test Management / 🐳 Docker Integration Tests (push) Blocked by required conditions
CI Pipeline with Test Management / 🏗️ Build Docker Image (push) Blocked by required conditions
CI Pipeline with Test Management / 📊 Generate Test Summary (push) Blocked by required conditions
Test Reporting & Gherkin Analysis / 🧪 Run Tests & Generate Reports (push) Waiting to run
Test Reporting & Gherkin Analysis / 📊 Analyze Test Coverage (push) Blocked by required conditions
Test Reporting & Gherkin Analysis / 🔄 Sync with Linear (push) Blocked by required conditions
Test Reporting & Gherkin Analysis / ⚡ Performance Monitoring (push) Blocked by required conditions
- home.json gains a partners block (title/subtitle/items: name, url, logo),
rendered on the homepage under the services section (next/image logos
linking out with rel=noopener)
- CMS: partner logos uploadable from the 🎨 Logó page via POST /partner-logo
(PNG, 1 MiB cap, filename sanitized to a slug, written to public/partners/)
- schema + types extended; guide updated
Closes MITHOME-83
This commit is contained in:
@@ -132,6 +132,44 @@ async function main() {
|
||||
{ method: 'POST', headers: { 'Content-Type': 'image/png', 'X-CSRF-Token': csrf }, body: TINY_PNG });
|
||||
assert.equal(anon.status, 401);
|
||||
|
||||
// 4. partner logo upload (MITHOME-83)
|
||||
const partnerDir = path.join(ROOT, 'proto', 'public', 'partners');
|
||||
const partnerFile = path.join(partnerDir, 'acme.png');
|
||||
try {
|
||||
const up = await fetch(`${BASE}/partner-logo?name=acme`, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'image/png', 'X-CSRF-Token': csrf, 'Cookie': cookie },
|
||||
body: TINY_PNG,
|
||||
});
|
||||
assert.equal(up.status, 200);
|
||||
const body = await up.json();
|
||||
assert.equal(body.ok, true);
|
||||
assert.equal(body.path, '/partners/acme.png');
|
||||
assert.ok(fs.existsSync(partnerFile), 'partner logo file created');
|
||||
|
||||
// non-PNG → 415
|
||||
const bad = await fetch(`${BASE}/partner-logo?name=x`, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'image/png', 'X-CSRF-Token': csrf, 'Cookie': cookie },
|
||||
body: Buffer.from('not a png'),
|
||||
});
|
||||
assert.equal(bad.status, 415);
|
||||
|
||||
// traversal name is sanitized (no path escape)
|
||||
const trav = await fetch(`${BASE}/partner-logo?name=../evil`, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'image/png', 'X-CSRF-Token': csrf, 'Cookie': cookie },
|
||||
body: TINY_PNG,
|
||||
});
|
||||
assert.equal(trav.status, 200);
|
||||
const tBody = await trav.json();
|
||||
assert.ok(tBody.path.startsWith('/partners/'), 'traversal name is sanitized to a safe slug');
|
||||
assert.ok(!tBody.path.includes('..'), 'no traversal in the returned path');
|
||||
} finally {
|
||||
try { fs.unlinkSync(partnerFile); } catch { /* noop */ }
|
||||
try { fs.rmdirSync(partnerDir); } catch { /* not empty */ }
|
||||
}
|
||||
|
||||
console.log('Content Editor logo upload test: OK');
|
||||
} finally {
|
||||
fs.writeFileSync(iconPath, originalIcon);
|
||||
|
||||
Reference in New Issue
Block a user