From fe005c04222739643f5a7ce600e3ca225d3edb49 Mon Sep 17 00:00:00 2001 From: fontvielle Date: Mon, 12 Oct 2026 21:15:49 +0300 Subject: [PATCH] =?UTF-8?q?fix(emulators):=20=D0=BF=D0=BE=D0=B4=D0=BC?= =?UTF-8?q?=D0=B5=D0=BD=D0=B0=20=D0=BB=D0=B8=D1=87=D0=BD=D0=BE=D1=81=D1=82?= =?UTF-8?q?=D0=B8=20=D0=B2=20=D0=9D=D0=A0=D0=94=20=D0=B3=D0=B0=D1=81=D0=BD?= =?UTF-8?q?=D0=B5=D1=82=20=D0=BF=D0=BE=20=D0=BE=D0=BA=D0=BE=D0=BD=D1=87?= =?UTF-8?q?=D0=B0=D0=BD=D0=B8=D0=B8=20dev-=D1=80=D0=B5=D0=B6=D0=B8=D0=BC?= =?UTF-8?q?=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit disableEmulatorsIfDevOff сбрасывал только LK.EmulateNSD / Quik.Emulate / Quik.RealWrite, но не LK.RealNSDTest.Enabled (тест «боевой ЛК → TEST3»). Из-за этого после истечения dev-режима подмена инвестора оставалась включённой, а клиент без доступа к dev-вкладкам не мог вернуть стандартный режим. Теперь сброс LK объединён в одно обновление и гасит и подмену (список паспортов сохраняется). + тест TestDisableEmulatorsIfDevOffRealNSD. Co-Authored-By: Claude Opus 4.8 --- internal/lkgateway/emulators.go | 26 +++++++++++++------ internal/lkgateway/emulators_test.go | 37 ++++++++++++++++++++++++++++ 2 files changed, 55 insertions(+), 8 deletions(-) diff --git a/internal/lkgateway/emulators.go b/internal/lkgateway/emulators.go index fcf5584..c3e0274 100644 --- a/internal/lkgateway/emulators.go +++ b/internal/lkgateway/emulators.go @@ -186,26 +186,36 @@ func emuOutcomeRu(outcome string) string { return "подтверждение" } -// disableEmulatorsIfDevOff — безопасность: эмуляторы НРД/МНП действуют только в режиме -// разработки; когда он заканчивается (по времени dev_until или снят на сервере лицензий), -// флаги сбрасываются из настроек — иначе при следующей выдаче dev-режима эмуляция -// молча оживёт. Вызывается при старте и в цикле продления лицензии. +// disableEmulatorsIfDevOff — безопасность: эмуляторы НРД/МНП и подмена личности в НРД +// («боевой ЛК → тестовый контур») действуют только в режиме разработки; когда он +// заканчивается (по времени dev_until или снят на сервере лицензий), флаги сбрасываются из +// настроек — иначе при следующей выдаче dev-режима эмуляция/подмена молча оживёт, а клиент +// без доступа к dev-вкладкам не смог бы вернуть стандартный режим. Вызывается при старте и в +// цикле продления лицензии. func disableEmulatorsIfDevOff(rc *RuntimeConfig) { if rc == nil || devMode(rc) { return } s := rc.Snapshot() - if !s.LK.EmulateNSD && !s.Quik.Emulate && !s.Quik.RealWrite { + if !s.LK.EmulateNSD && !s.LK.RealNSDTest.Enabled && !s.Quik.Emulate && !s.Quik.RealWrite { return } var off []string - if s.LK.EmulateNSD { + // Эмулятор НРД и подмена личности («боевой ЛК → тестовый контур НРД») — оба в настройках LK; + // сбрасываем одним обновлением, чтобы без режима разработки заявки шли под своими данными. + if s.LK.EmulateNSD || s.LK.RealNSDTest.Enabled { lk := s.LK lk.EmulateNSD = false + lk.RealNSDTest.Enabled = false if err := rc.UpdateLK(lk); err != nil { - log.Printf("lk-gateway: авто-сброс эмулятора НРД: %v", err) + log.Printf("lk-gateway: авто-сброс эмулятора/подмены НРД: %v", err) } else { - off = append(off, "эмулятор НРД (заявки ЛК)") + if s.LK.EmulateNSD { + off = append(off, "эмулятор НРД (заявки ЛК)") + } + if s.LK.RealNSDTest.Enabled { + off = append(off, "подмена личности в НРД (тест «боевой ЛК → TEST3»)") + } } } if s.Quik.Emulate || s.Quik.RealWrite { diff --git a/internal/lkgateway/emulators_test.go b/internal/lkgateway/emulators_test.go index bc2bd1a..f2df31d 100644 --- a/internal/lkgateway/emulators_test.go +++ b/internal/lkgateway/emulators_test.go @@ -302,6 +302,43 @@ func TestDisableEmulatorsIfDevOffNoOp(t *testing.T) { } } +// Подмена личности в НРД («боевой ЛК → TEST3») тоже гаснет по окончании dev-режима: +// иначе клиент без доступа к dev-вкладкам не вернул бы стандартный режим. +func TestDisableEmulatorsIfDevOffRealNSD(t *testing.T) { + rc := rcWithExpiredDev(t) + s := rc.Snapshot() + s.LK.RealNSDTest.Enabled = true + s.LK.RealNSDTest.Docs = "1110 754503" + if err := rc.UpdateLK(s.LK); err != nil { + t.Fatal(err) + } + disableEmulatorsIfDevOff(rc) + if rc.Snapshot().LK.RealNSDTest.Enabled { + t.Fatal("подмена личности не сброшена") + } + // Паспорта клиентов сохраняем — сбрасываем только включатель. + if rc.Snapshot().LK.RealNSDTest.Docs != "1110 754503" { + t.Errorf("список паспортов не должен затираться: %q", rc.Snapshot().LK.RealNSDTest.Docs) + } + // На диске тоже выключено — при следующем dev-режиме подмена сама не оживёт. + rc2, err := NewRuntimeConfig(rc.path) + if err != nil { + t.Fatal(err) + } + if rc2.Snapshot().LK.RealNSDTest.Enabled { + t.Fatal("в setup.json подмена осталась включённой") + } + found := false + for _, n := range rc.Snapshot().News.Items { + if strings.Contains(n.Title, "Эмуляторы отключены") && strings.Contains(n.Body, "подмена личности") { + found = true + } + } + if !found { + t.Error("в новости не упомянуто отключение подмены личности") + } +} + // Режимы МНП взаимоисключающие: хендлер выставляет Emulate/RealWrite по выбранному режиму. func TestEmulatorsQuikModes(t *testing.T) { devModeForced = true