From db632c2558cb4efc57bbe07cd2e6d11d8cfcb771 Mon Sep 17 00:00:00 2001 From: Dmitry Dementiev Date: Tue, 18 Aug 2026 12:46:16 +0300 Subject: [PATCH] =?UTF-8?q?test(generator):=20=D0=B0=D0=BD=D0=BE=D0=BD?= =?UTF-8?q?=D0=B8=D0=BC=D0=BD=D0=BE=D1=81=D1=82=D1=8C=20=D1=81=D0=BE=D0=B1?= =?UTF-8?q?=D1=8B=D1=82=D0=B8=D1=8F=20=D0=BF=D1=80=D0=BE=D0=B2=D0=B5=D1=80?= =?UTF-8?q?=D1=8F=D0=B5=D1=82=D1=81=D1=8F=20=D0=B8=20=D1=82=D0=B5=D0=BA?= =?UTF-8?q?=D1=81=D1=82=D0=BE=D0=BC,=20=D0=BD=D0=B5=20=D1=82=D0=BE=D0=BB?= =?UTF-8?q?=D1=8C=D0=BA=D0=BE=20=D1=87=D0=B8=D1=81=D0=BB=D0=BE=D0=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Зачем: - холодное ревью Кодексом (линия дефектов) показало дыру в проверке анонимности: личность, уехавшая строкой в сыром `ecommerce`, проходила мимо сравнения числовых колонок, и тест оставался зелёным. Дыра воспроизведена: user_id, дописанный в блок покупки, тест не замечал. - Что: - тест анонимности спрашивает двумя способами: числовые колонки дня — со всеми личностями аудитории, строки покупок целиком — с личностями покупателей. Сырой блок собирается руками, и лишнее поле в нём теперь красит проверку. - Проверка: - из `generator/`: make lint, make typecheck, make test (417 тестов). - мутация «дописать user_id в ecommerce покупки»: до правки тест зелёный, после — красный. Co-Authored-By: Claude Opus 5 --- generator/tests/test_orders.py | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/generator/tests/test_orders.py b/generator/tests/test_orders.py index 183fc80..2dff566 100644 --- a/generator/tests/test_orders.py +++ b/generator/tests/test_orders.py @@ -189,9 +189,12 @@ def test_both_cookies_of_a_pair_order_as_one_user(week: list[day.Day]): def test_the_user_id_never_reaches_the_metrica_event(weekday: day.Day): """Кликстрим анонимен: личность держится формой контракта, а не забывчивостью. - Проверяются числовые колонки события целиком: личность — число того же - порядка, что кука и номер события, и попасть она могла бы только в - такую. Имени для неё в контракте нет вовсе. + Спрашивается двумя способами, потому что утечь личность может двумя. + Числом — тогда её видно в числовых колонках дня, и они сверяются со + всеми личностями дневной аудитории. Текстом — тогда сравнение чисел + её прозевало бы, поэтому строки покупок читаются целиком, вместе с + сырым `ecommerce`: этот блок собирается руками, и дописать в него + лишнее поле проще всего. Имени для личности в контракте схемы нет. """ people = set(plan.audience(CANONICAL_SEED, WEEKDAY).person_id.tolist()) assert people @@ -200,4 +203,12 @@ def test_the_user_id_never_reaches_the_metrica_event(weekday: day.Day): for name, value in weekday.columns.items(): if np.issubdtype(value.dtype, np.integer): assert not (set(value.tolist()) & people), name + + events = purchases_of(weekday) + text = "\n".join( + " ".join(str(value[row]) for value in events.values()) + for row in range(events["WatchID"].size) + ) + for person in weekday.orders.user_id.tolist(): + assert str(person) not in text assert set(weekday.orders.user_id.tolist()) <= people