32df332901
Приёмка глазами вскрыла: кабинет МТС требует «Заголовок объявления» (до 40 знаков), когда в объявлении ссылка на САЙТ, а не на телеграм-канал. Робот про это поле не знал, «Продолжить» молча не срабатывало, кампания вставала на шаге «Объявление» — в бою уже ПОСЛЕ списания денег. Проверено живьём: 2234454 (сайт — встала) против 2234462 (канал — дошла до подтверждения) и 2234490 (сайт с заголовком — дошла). Портал спрашивает заголовок заранее, на создании черновика: обязателен только для не-телеграмной ссылки (App\Support\TelegramLink), колонка ad_headline varchar(40), поле на экране появляется по той же развилке. Робот заполняет его в кабинете. Три ловушки, добытые живыми прогонами (описаны в коде): - поле дорисовывается в ОТВЕТ на ссылку, с задержкой — надо ждать, а не спрашивать; - под описание подходит несколько элементов — нужен .first(); - серая надпись внутри поля НЕ placeholder, а нарисованная подпись: поиск по атрибуту давал ноль совпадений при видимом на снимке поле. Опознаём по видимой надписи. Тесты: робот 130/130, ClientTg 250/250, экран 23/23. Полный прогон бэкенда — те же 13 падающих классов до и после правки (ни одного в телеграм-части). В baseline статанализа добавлен известный ложный класс Pest для нового файла тестов. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
74 lines
3.0 KiB
JavaScript
74 lines
3.0 KiB
JavaScript
import { test } from 'node:test';
|
|
import assert from 'node:assert/strict';
|
|
import { parseTask } from '../src/task.js';
|
|
|
|
const base = {
|
|
phonesFile: 'phones.txt', adText: 'Короткий текст',
|
|
budgetRub: 1000, buttonUrl: 'https://site.ru',
|
|
mode: 'draft',
|
|
};
|
|
|
|
test('parseTask принимает корректное задание', () => {
|
|
const t = parseTask(base);
|
|
assert.equal(t.mode, 'draft');
|
|
assert.equal(t.budgetRub, 1000);
|
|
});
|
|
|
|
test('parseTask отвергает неизвестный режим', () => {
|
|
assert.throws(() => parseTask({ ...base, mode: 'xxx' }), /mode/);
|
|
});
|
|
|
|
test('parseTask требует phonesFile', () => {
|
|
const { phonesFile, ...rest } = base;
|
|
assert.throws(() => parseTask(rest), /phonesFile/);
|
|
});
|
|
|
|
test('parseTask отвергает пустой текст', () => {
|
|
assert.throws(() => parseTask({ ...base, adText: '' }), /adText/);
|
|
});
|
|
|
|
test('parseTask требует budgetRub > 0', () => {
|
|
assert.throws(() => parseTask({ ...base, budgetRub: 0 }), /budgetRub/);
|
|
});
|
|
|
|
test('parseTask подставляет дефолт ordCategory', () => {
|
|
const t = parseTask(base);
|
|
assert.equal(t.ordCategory, 'Размещение рекламы');
|
|
});
|
|
|
|
test('parseTask пробрасывает заданную ordCategory', () => {
|
|
const t = parseTask({ ...base, ordCategory: 'Другая категория' });
|
|
assert.equal(t.ordCategory, 'Другая категория');
|
|
});
|
|
|
|
test('parseTask НЕ требует adTitle/ordCompanyName (полей в кабинете нет)', () => {
|
|
// Задание без adTitle/ordCompanyName/cpmRub должно проходить.
|
|
const t = parseTask(base);
|
|
assert.equal(t.adTitle, undefined);
|
|
assert.equal(t.ordCompanyName, undefined);
|
|
assert.equal(t.cpmRub, undefined);
|
|
});
|
|
|
|
test('parseTask пробрасывает moderatorFile (документ модератору, пересдача 3.6)', () => {
|
|
const t = parseTask({ ...base, moderatorFile: 'C:/tmp/licenziya.pdf' });
|
|
assert.equal(t.moderatorFile, 'C:/tmp/licenziya.pdf');
|
|
});
|
|
|
|
test('parseTask: без moderatorFile → null (документ не приложили)', () => {
|
|
const t = parseTask(base);
|
|
assert.equal(t.moderatorFile, null);
|
|
});
|
|
|
|
// 31.07.2026, приёмка живьём: кабинет МТС показывает ОБЯЗАТЕЛЬНОЕ поле «Заголовок
|
|
// объявления» (до 40 знаков) и «Текст на кнопке», когда рекламируется САЙТ, а не
|
|
// телеграм-канал. Со ссылкой на сайт кампания вставала на шаге «Объявление».
|
|
test('parseTask пробрасывает adHeadline', () => {
|
|
const t = parseTask({ ...base, adHeadline: 'Лидерра' });
|
|
assert.equal(t.adHeadline, 'Лидерра');
|
|
});
|
|
|
|
test('parseTask: без заголовка → null (телеграм-ссылке он не нужен)', () => {
|
|
const t = parseTask(base);
|
|
assert.equal(t.adHeadline, null);
|
|
});
|