first unit test for badge endpoint

This commit is contained in:
2025-07-17 10:31:01 +02:00
parent c4146a2d65
commit 3774b40987
4 changed files with 3805 additions and 5 deletions
+3698
View File
File diff suppressed because it is too large Load Diff
+5 -1
View File
@@ -5,7 +5,7 @@
"main": "index.js", "main": "index.js",
"scripts": { "scripts": {
"start": "node src/index.js", "start": "node src/index.js",
"test": "echo \"Error: no test specified\" && exit 1" "test": "jest --coverage"
}, },
"repository": { "repository": {
"type": "git", "type": "git",
@@ -21,5 +21,9 @@
"axios": "^1.10.0", "axios": "^1.10.0",
"express": "^5.1.0", "express": "^5.1.0",
"helmet": "^8.1.0" "helmet": "^8.1.0"
},
"devDependencies": {
"jest": "^29.7.0",
"supertest": "^7.1.3"
} }
} }
+6 -2
View File
@@ -83,14 +83,14 @@ router.get('/badge', async (req, res) => {
`; `;
} else if (labelpos === 'above' || labelpos === 'below') { } else if (labelpos === 'above' || labelpos === 'below') {
// Felső vagy alsó label: ikon doboz magassága = iconSize + 5, szélessége = szöveg doboz szélessége // Felső vagy alsó label: ikon doboz magassága = iconSize + 5, szélessége = szöveg doboz szélessége
width = Math.max(iiconSizeAndPadding, textWidth); width = Math.max(iconSizeAndPadding, textWidth);
const iconRectY = labelpos === 'above' const iconRectY = labelpos === 'above'
? labelRectHeight ? labelRectHeight
: 0; : 0;
const labelRectY = labelpos === 'above' const labelRectY = labelpos === 'above'
? 0 ? 0
: iiconSizeAndPadding; : iconSizeAndPadding;
height = iconSizeAndPadding + textPadding + labelRectHeight; height = iconSizeAndPadding + textPadding + labelRectHeight;
// Label háttér // Label háttér
@@ -138,9 +138,13 @@ router.get('/badge', async (req, res) => {
res.setHeader('Content-Type', 'image/svg+xml'); res.setHeader('Content-Type', 'image/svg+xml');
res.send(svg); res.send(svg);
} catch (err) { } catch (err) {
if (err.response && err.response.status === 404) {
return res.status(404).send('Icon not found');
} else {
console.error(err); console.error(err);
res.status(500).send('Internal Server Error'); res.status(500).send('Internal Server Error');
} }
}
}); });
module.exports = router; module.exports = router;
+94
View File
@@ -0,0 +1,94 @@
const request = require('supertest');
const express = require('express');
const helmet = require('helmet');
const badgeRouter = require('../src/api/badge');
const app = express();
app.use(helmet({ crossOriginResourcePolicy: false }));
app.use(badgeRouter);
describe('GET /badge', () => {
it('should return SVG with default params', async () => {
const res = await request(app).get('/badge');
const resBody = Buffer.from(res.body).toString();
expect(res.statusCode).toBe(200);
expect(res.headers['content-type']).toMatch(/image\/svg\+xml/);
expect(resBody).toContain('<svg');
expect(resBody).toContain('<rect');
});
it('should use custom icon and label', async () => {
const res = await request(app).get('/badge?icon=github&label=GitHub');
const resBody = Buffer.from(res.body).toString();
expect(res.statusCode).toBe(200);
expect(resBody).toContain('GitHub');
expect(resBody).toContain('<svg');
});
it('should use label from SVG title if label param is missing', async () => {
const res = await request(app).get('/badge?icon=github');
const resBody = Buffer.from(res.body).toString();
expect(res.statusCode).toBe(200);
expect(resBody).toContain('<svg');
// The title from the SVG should be present as label
expect(resBody.toLowerCase()).toContain('github');
});
it('should set icon background to transparent', async () => {
const res = await request(app).get('/badge?bgicon=none');
const resBody = Buffer.from(res.body).toString();
expect(res.statusCode).toBe(200);
expect(resBody).toContain('fill="none"');
});
it('should set label background to transparent', async () => {
const res = await request(app).get('/badge?bglabel=none');
const resBody = Buffer.from(res.body).toString();
expect(res.statusCode).toBe(200);
expect(resBody).toContain('fill="none"');
});
it('should use flat style with rounded corners', async () => {
const res = await request(app).get('/badge?style=flat');
const resBody = Buffer.from(res.body).toString();
expect(res.statusCode).toBe(200);
expect(resBody).toContain('rx="');
});
it('should handle labelpos left', async () => {
const res = await request(app).get('/badge?labelpos=left');
const resBody = Buffer.from(res.body).toString();
expect(res.statusCode).toBe(200);
expect(resBody).toContain('<rect');
expect(resBody).toContain('<text');
});
it('should handle labelpos above', async () => {
const res = await request(app).get('/badge?labelpos=above');
const resBody = Buffer.from(res.body).toString();
expect(res.statusCode).toBe(200);
expect(resBody).toContain('<rect');
expect(resBody).toContain('<text');
});
it('should handle labelpos below', async () => {
const res = await request(app).get('/badge?labelpos=below');
const resBody = Buffer.from(res.body).toString();
expect(res.statusCode).toBe(200);
expect(resBody).toContain('<rect');
expect(resBody).toContain('<text');
});
it('should handle custom fontweight', async () => {
const res = await request(app).get('/badge?fontweight=bold');
const resBody = Buffer.from(res.body).toString();
expect(res.statusCode).toBe(200);
expect(resBody).toContain('font-weight="bold"');
});
// Test not applicable, since icon is not real should handle 404 from CDN
it('should return 404 for unknown icon', async () => {
const res = await request(app).get('/badge?icon=notarealicon');
expect(res.statusCode).toBe(404);
});
});