Page consommant /api/audit-trail/recent avec auto-refresh PrimeFaces toutes les 10s. Transparency opérationnelle UnionFlow — chaque utilisateur voit selon son scope. REST client AuditTrailRestClient - Nouvelle méthode recent(scope, orgId, userId, limit) Bean LiveFeedBean (@ViewScoped) - Polling pilote externe via p:poll interval=10 - 3 scopes : SELF (défaut, n'importe quel rôle), ORG (admin/officer), ALL (compliance/contrôleur) - Helpers : couleurAction (8 mappings), couleurSod (3 cas), tempsRelatif (s/m/h/j/futur) - Limit clamp [1, 500] - Compteur de refresh visible dans l'UI (debug) Page /pages/secure/conformite/live-feed.xhtml - Panel scope avec selectOneMenu + p:ajax change → rafraîchir - Conditional inputs : orgId si scope=ORG, userId si scope=SELF - p:poll interval=10 listener=rafraichir autoStart=true - DataTable opérations : index, "il y a Xs", acteur+rôle, action coloré, entité, description, SoD tag - Tag refresh counter (visible feedback) Centralisation - ViewPaths.CONFORMITE_LIVE_FEED + getter ViewPathsBean - menu.xhtml : entrée Live Feed sous sous-menu Conformité (icon pi-bolt) Tests (13/13 verts) - couleurAction × 4 (danger/success/info/autres) - couleurSod - tempsRelatif × 6 (null, secondes, minutes, heures, jours, futur) - setLimit clamp × 4 - defaults
131 lines
4.4 KiB
Java
131 lines
4.4 KiB
Java
package dev.lions.unionflow.client.view;
|
|
|
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
|
import static org.junit.jupiter.api.Assertions.assertTrue;
|
|
|
|
import java.time.LocalDateTime;
|
|
import org.junit.jupiter.api.BeforeEach;
|
|
import org.junit.jupiter.api.DisplayName;
|
|
import org.junit.jupiter.api.Test;
|
|
|
|
class LiveFeedBeanTest {
|
|
|
|
private LiveFeedBean bean;
|
|
|
|
@BeforeEach
|
|
void setUp() {
|
|
bean = new LiveFeedBean();
|
|
}
|
|
|
|
// ── couleurAction (mêmes règles que AuditTrailViewerBean) ────────────
|
|
|
|
@Test
|
|
@DisplayName("couleurAction — DELETE/PAYMENT_FAILED → danger")
|
|
void couleurDanger() {
|
|
assertEquals("danger", bean.getCouleurAction("DELETE"));
|
|
assertEquals("danger", bean.getCouleurAction("PAYMENT_FAILED"));
|
|
}
|
|
|
|
@Test
|
|
@DisplayName("couleurAction — VALIDATE/PAYMENT_CONFIRMED/AID_REQUEST_APPROVED → success")
|
|
void couleurSuccess() {
|
|
assertEquals("success", bean.getCouleurAction("VALIDATE"));
|
|
assertEquals("success", bean.getCouleurAction("PAYMENT_CONFIRMED"));
|
|
assertEquals("success", bean.getCouleurAction("AID_REQUEST_APPROVED"));
|
|
}
|
|
|
|
@Test
|
|
@DisplayName("couleurAction — UPDATE/PAYMENT_INITIATED/BUDGET_APPROVED → info")
|
|
void couleurInfo() {
|
|
assertEquals("info", bean.getCouleurAction("UPDATE"));
|
|
assertEquals("info", bean.getCouleurAction("PAYMENT_INITIATED"));
|
|
assertEquals("info", bean.getCouleurAction("BUDGET_APPROVED"));
|
|
}
|
|
|
|
@Test
|
|
@DisplayName("couleurAction — CREATE → primary, EXPORT → warning, autres → secondary")
|
|
void couleurAutres() {
|
|
assertEquals("primary", bean.getCouleurAction("CREATE"));
|
|
assertEquals("warning", bean.getCouleurAction("EXPORT"));
|
|
assertEquals("secondary", bean.getCouleurAction(null));
|
|
assertEquals("secondary", bean.getCouleurAction("INCONNU"));
|
|
}
|
|
|
|
@Test
|
|
@DisplayName("couleurSod — true→success, false→danger, null→secondary")
|
|
void couleurSod() {
|
|
assertEquals("success", bean.getCouleurSod(true));
|
|
assertEquals("danger", bean.getCouleurSod(false));
|
|
assertEquals("secondary", bean.getCouleurSod(null));
|
|
}
|
|
|
|
// ── tempsRelatif ─────────────────────────────────────────────────────
|
|
|
|
@Test
|
|
@DisplayName("tempsRelatif — null → '—'")
|
|
void tempsRelatifNull() {
|
|
assertEquals("—", bean.tempsRelatif(null));
|
|
}
|
|
|
|
@Test
|
|
@DisplayName("tempsRelatif — 30s ago → 'il y a 30s'")
|
|
void tempsRelatifSecondes() {
|
|
LocalDateTime past = LocalDateTime.now().minusSeconds(30);
|
|
assertTrue(bean.tempsRelatif(past).startsWith("il y a "));
|
|
assertTrue(bean.tempsRelatif(past).endsWith("s"));
|
|
}
|
|
|
|
@Test
|
|
@DisplayName("tempsRelatif — 5min ago → 'il y a 5m'")
|
|
void tempsRelatifMinutes() {
|
|
LocalDateTime past = LocalDateTime.now().minusMinutes(5);
|
|
assertEquals("il y a 5m", bean.tempsRelatif(past));
|
|
}
|
|
|
|
@Test
|
|
@DisplayName("tempsRelatif — 2h ago → 'il y a 2h'")
|
|
void tempsRelatifHeures() {
|
|
LocalDateTime past = LocalDateTime.now().minusHours(2);
|
|
assertEquals("il y a 2h", bean.tempsRelatif(past));
|
|
}
|
|
|
|
@Test
|
|
@DisplayName("tempsRelatif — 3 jours ago → 'il y a 3j'")
|
|
void tempsRelatifJours() {
|
|
LocalDateTime past = LocalDateTime.now().minusDays(3);
|
|
assertEquals("il y a 3j", bean.tempsRelatif(past));
|
|
}
|
|
|
|
@Test
|
|
@DisplayName("tempsRelatif — futur → 'à l'instant'")
|
|
void tempsRelatifFutur() {
|
|
LocalDateTime futur = LocalDateTime.now().plusMinutes(1);
|
|
assertEquals("à l'instant", bean.tempsRelatif(futur));
|
|
}
|
|
|
|
// ── Limit clamping ───────────────────────────────────────────────────
|
|
|
|
@Test
|
|
@DisplayName("setLimit clamp [1, 500]")
|
|
void setLimitClamp() {
|
|
bean.setLimit(0);
|
|
assertEquals(1, bean.getLimit());
|
|
bean.setLimit(1000);
|
|
assertEquals(500, bean.getLimit());
|
|
bean.setLimit(50);
|
|
assertEquals(50, bean.getLimit());
|
|
bean.setLimit(-100);
|
|
assertEquals(1, bean.getLimit());
|
|
}
|
|
|
|
// ── Defaults ─────────────────────────────────────────────────────────
|
|
|
|
@Test
|
|
@DisplayName("Defaults — scope=SELF, limit=50, compteur=0")
|
|
void defaults() {
|
|
assertEquals("SELF", bean.getScope());
|
|
assertEquals(50, bean.getLimit());
|
|
assertEquals(0, bean.getCompteur());
|
|
}
|
|
}
|