Fenetre d'export : portee au curseur, format en segments

Le menu de portee proposait « 25 derniers echanges » sur un fil qui en
comptait trois, et ne disait nulle part combien il y en avait. Un
curseur le remplace, borne au nombre REEL d'echanges, butee droite =
toute la conversation. Sous la piste : le compte (« 3 derniers echanges
sur 12 ») et le POIDS du fichier pour les options courantes, sonde
cote serveur (probe=1, rendu puis jete, donc jamais un second calcul de
taille qui divergerait).

Le format passe en controle segmente (.seg), celui du choix de moteur
dans l'editeur de preset : deux cases cote a cote au lieu de deux
boutons radio empiles.

Deux details qui faussaient l'affichage : une sonde encore en vol
revenait ecraser le « … » par la taille de l'etat PRECEDENT (le poids
retardait d'un cran sur le curseur), et fmtSize arrondissait 2585
octets en « 3 KB » dans le seul endroit qui pretend annoncer la taille
reelle.
This commit is contained in:
nathaninline committed 2026-08-08 20:39:58 +02:00
1 parent 7a27dbf3be
commit b7042f1127
6 files changed
+322 -28

No files matched your search

+40
View File
@@ -204,6 +204,46 @@ func TestExportDerniersEchanges(t *testing.T) {
}
}
// La sonde alimente le curseur de portée et la taille annoncée : elle doit
// rendre la taille EXACTE du fichier qui serait téléchargé avec les mêmes
// options, sinon l'interface annonce un poids qu'elle ne tient pas.
func TestHandleChatExportProbe(t *testing.T) {
convDeTest(t)
probe := func(q string) (size, turns int) {
rr := httptest.NewRecorder()
handleChatExport(rr, httptest.NewRequest("GET", "/api/chat/export?probe=1&"+q, nil))
if rr.Code != 200 {
t.Fatalf("%s : HTTP %d", q, rr.Code)
}
var out struct {
Size int `json:"size"`
Turns int `json:"turns"`
}
if err := json.Unmarshal(rr.Body.Bytes(), &out); err != nil {
t.Fatal(err)
}
return out.Size, out.Turns
}
download := func(q string) int {
rr := httptest.NewRecorder()
handleChatExport(rr, httptest.NewRequest("GET", "/api/chat/export?"+q, nil))
return rr.Body.Len()
}
for _, q := range []string{"", "reasoning=0", "format=json", "turns=1"} {
if s, _ := probe(q); s != download(q) {
t.Errorf("q=%q : sonde %d o, téléchargement %d o", q, s, download(q))
}
}
// Le compte d'échanges ne dépend PAS des options : c'est la borne du curseur,
// elle ne doit pas rétrécir quand on réduit la portée.
if _, n := probe("turns=1"); n != 1 {
t.Errorf("échanges comptés = %d ; le fil de test en a 1", n)
}
if got := conv.countTurns(); got != 1 {
t.Errorf("countTurns = %d", got)
}
}
func TestCmdExportEcritLeFichier(t *testing.T) {
testHome(t)
convDeTest(t)