feat: perinco Pulse - Zeiterfassung fuer perinco
Erste Fassung, live unter https://pulse.perinco.de. Frontend React 19 + TypeScript + Tailwind 4 (Vite), Backend Express mit mysql2 auf MariaDB, Exporte als PDF (pdfkit), Excel (exceljs) und CSV. Aufbau, Designsystem und die sieben Themes kommen aus dem perinco CRM. Fachlich: - Buchung mit Wochen-, Monats- und Jahresansicht, Zeiten als 1:23 oder 1,5 - Projekte mit n Budgettoepfen: Laufzeit, Volumen, Sperre bei Ablauf oder aufgebrauchtem Budget, Buchung nur auf den passenden Topf - Kunden, Team mit Hierarchie, Reports im Harvest-Stil, Monatsexporte - Rollen user/lead/management/admin, doppelt geprueft (Menue und Backend) - SSO gegen Microsoft Entra ID, Uebernahme der AD-Benutzer per Drag & Drop Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,49 @@
|
||||
import { test } from 'node:test';
|
||||
import assert from 'node:assert/strict';
|
||||
import { isEligible } from '../src/lib/sso.js';
|
||||
|
||||
const user = (mail, surname, extra = {}) => ({
|
||||
mail,
|
||||
surname,
|
||||
userType: 'Member',
|
||||
accountEnabled: true,
|
||||
assignedLicenses: [{ skuId: 'x' }],
|
||||
...extra,
|
||||
});
|
||||
|
||||
test('Mitarbeiterkonten beider Domains werden angezeigt', () => {
|
||||
assert.equal(isEligible(user('sascha.wolf@perinco.de', 'Wolf')), true);
|
||||
assert.equal(isEligible(user('Sascha.Wolf@PERINCO.de', 'Wolf')), true);
|
||||
assert.equal(isEligible(user('kai.schwickert@icon-experts.de', 'Schwickert')), true);
|
||||
assert.equal(isEligible(user('timo.grote-aksu@perinco.de', 'Grote-Aksu')), true);
|
||||
assert.equal(isEligible(user('niklas.muelln@perinco.de', 'Mülln')), true);
|
||||
assert.equal(isEligible(user('rene.kleinau@perinco.de', 'Kleinau', { givenName: 'René' })), true);
|
||||
// Tippfehler im Vornamen (AD: "Chrisitan") schadet nicht.
|
||||
assert.equal(isEligible(user('christian.brix@perinco.de', 'Brix', { givenName: 'Chrisitan' })), true);
|
||||
assert.equal(isEligible(user('merle.schwegler@perinco.de', 'Schwegler', { givenName: 'Merle Sophie' })), true);
|
||||
});
|
||||
|
||||
test('Admin-, Dienst- und Funktionskonten werden ignoriert', () => {
|
||||
assert.equal(isEligible(user('adm.sascha.wolf@perinco.de', 'Wolf')), false);
|
||||
assert.equal(isEligible(user('sa.hrworks@perinco.de', 'Account', { givenName: 'Service' })), false);
|
||||
assert.equal(isEligible(user('srv.pa@perinco.de', 'Flow', { givenName: 'SRV' })), false);
|
||||
assert.equal(isEligible(user('srv.flow@perinco.de', 'Flow')), false);
|
||||
assert.equal(isEligible(user('info@perinco.de', 'Info')), false);
|
||||
assert.equal(isEligible(user('max.muster@perinco.de', undefined)), false);
|
||||
});
|
||||
|
||||
test('Fremde Domains und falsche Formate werden ignoriert', () => {
|
||||
for (const mail of ['sascha.wolf@perinco.com', 'sascha.wolf@sub.perinco.de', 'sascha.wolf2@perinco.de', 'sascha..wolf@perinco.de', '']) {
|
||||
assert.equal(isEligible(user(mail, 'Wolf')), false, mail);
|
||||
}
|
||||
});
|
||||
|
||||
test('Freigegebene Postfaecher, Gaeste und Konten ohne Lizenz werden ignoriert', () => {
|
||||
assert.equal(isEligible(user('philip.daum@perinco.de', 'Daum', { accountEnabled: false })), false);
|
||||
assert.equal(isEligible(user('lisa.gast@perinco.de', 'Gast', { userType: 'Guest' })), false);
|
||||
assert.equal(isEligible(user('sven.krueger@perinco.de', 'Krüger', { assignedLicenses: [] })), false);
|
||||
});
|
||||
|
||||
test('Ohne mail zaehlt der UPN', () => {
|
||||
assert.equal(isEligible({ userPrincipalName: 'jonas.korn@perinco.de', surname: 'Korn', accountEnabled: true, assignedLicenses: [{}] }), true);
|
||||
});
|
||||
Reference in New Issue
Block a user