# Тестовые кейсы: JDBC-коннектор

## 1. Управление драйверами — Валидация файла

### TC-DRV-001 Загрузка валидного .jar-файла драйвера

**Предусловия:** пользователь с ролью «Администратор системы», реестр пуст

**Шаги:**

1. Перейти в Панель администратора → Настройки → «JDBC-драйверы»
2. Нажать «Добавить драйвер»
3. Заполнить поле «Тип» (например, PostgreSQL), версию и описание
4. Выбрать валидный .jar-файл официального PostgreSQL-драйвера
5. Нажать «Добавить»

**Ожидаемый результат:** драйвер появляется в таблице со статусом «Активен» (или «Требует проверки», если есть подозрительные, но не критические нарушения); запись есть в реестре; файл сохранён в хранилище.

---

### TC-DRV-002 Отклонение файла с расширением .txt

**Предусловия:** пользователь «Администратор системы»

**Шаги:**

1. Открыть окно «Добавление драйвера»
2. Попытаться выбрать файл с расширением .txt через filepicker

**Ожидаемый результат:** filepicker не позволяет выбрать файл — он недоступен для выбора (фильтр расширений .jar).

---

### TC-DRV-003 Отклонение повреждённого .jar-файла

**Предусловия:** подготовлен .jar-файл с нарушенной структурой ZIP

**Шаги:**

1. Открыть окно «Добавление драйвера»
2. Выбрать повреждённый .jar-файл, заполнить поля, нажать «Добавить»

**Ожидаемый результат:** появляется всплывающая ошибка «Валидация драйвера не пройдена: обнаружены критические нарушения безопасности или целостности файла»; драйвер не создаётся; окно не закрывается.

---

### TC-DRV-004 Отклонение .jar-файла без манифеста META-INF/MANIFEST.MF

**Шаги:**

1. Подготовить .jar без файла META-INF/MANIFEST.MF
2. Попытаться загрузить его как драйвер

**Ожидаемый результат:** ошибка валидации; статус критический; драйвер не сохраняется.

---

### TC-DRV-005 Отклонение файла размером ≥ 100 MB

**Шаги:**

1. Подготовить .jar ≥ 100 MB
2. Попытаться загрузить

**Ожидаемый результат:** ошибка валидации «Валидация файла не пройдена. Ошибка: ...»; файл не сохраняется.

---

### TC-DRV-006 Блокировка драйвера с хэшем из чёрного списка

**Предусловия:** хэш-сумма тестового файла добавлена в черный список уязвимых

**Шаги:**

1. Попытаться загрузить .jar с известным уязвимым хэшем

**Ожидаемый результат:** ошибка валидации; файл не сохраняется.

---

### TC-DRV-007 Блокировка драйвера с запрещёнными классами (JNDI)

**Предусловия:** подготовлен .jar с JNDI-классами или использованием `InitialContext`

**Шаги:**

1. Попытаться загрузить такой .jar

**Ожидаемый результат:** ошибка валидации с критическим статусом; загрузка отклонена.

---

### TC-DRV-008 Блокировка драйвера с вредоносным `static {}` блоком

**Шаги:**

1. Загрузить .jar, содержащий класс с `static { Runtime.getRuntime().exec(...) }`

**Ожидаемый результат:** ошибка валидации; критическое нарушение; загрузка отклонена.

---

### TC-DRV-009 Отклонение драйвера без обязательных мета-методов

**Шаги:**

1. Загрузить .jar, в котором отсутствуют методы `getTables` / `getColumns` / `getImportedKeys` / `getColumnName` / `getColumnType` / `getScale` / `getColumnCount`

**Ожидаемый результат:** ошибка валидации; критический статус; файл не принимается.

---

### TC-DRV-010 Статус «Требует проверки» при подозрительных признаках

**Шаги:**

1. Загрузить валидный .jar, содержащий нативную библиотеку (.so), но без критических нарушений

**Ожидаемый результат:** драйвер сохранён, статус «Требует проверки» (жёлтый).

---

### TC-DRV-011 Уникальность пары Тип + Версия

**Предусловия:** в реестре уже есть драйвер PostgreSQL версии 42.6.0

**Шаги:**

1. Попытаться загрузить ещё один драйвер с теми же Тип = PostgreSQL и Версия = 42.6.0

**Ожидаемый результат:** ошибка валидации; дубликат не создаётся.

---

## 2. Управление драйверами — CRUD через API

### TC-DRV-012 POST /drivers — успешное создание

**Шаги:**

1. Отправить POST-запрос с валидным .jar, типом, версией, описанием, от имени администратора системы

**Ожидаемый результат:** HTTP 201; в ответе — id новой записи; запись появляется в БД и файл в хранилище.

---

### TC-DRV-013 POST /drivers — доступ запрещён для роли «Разработчик»

**Шаги:**

1. Отправить POST-запрос от имени пользователя с ролью «Разработчик»

**Ожидаемый результат:** HTTP 403; запрос отклонён.

---

### TC-DRV-014 GET /drivers — список драйверов

**Шаги:**

1. Отправить GET-запрос от имени администратора системы

**Ожидаемый результат:** HTTP 200; в ответе список объектов: id, тип, версия, описание, статус; пароли и файлы в ответе отсутствуют.

---

### TC-DRV-015 PATCH /drivers/{id} — обновление версии драйвера

**Предусловия:** драйвер с id существует

**Шаги:**

1. Отправить PATCH-запрос с новым .jar-файлом и обновлённой версией

**Ожидаемый результат:** старый .jar удалён, новый сохранён; статус записи сброшен на «Требует проверки» до завершения повторной валидации; метаданные обновлены.

---

### TC-DRV-016 DELETE /drivers/{id} — удаление неиспользуемого драйвера

**Шаги:**

1. Отправить DELETE-запрос для драйвера, не связанного ни с одним источником

**Ожидаемый результат:** HTTP 200; запись удалена из БД; файл удалён из хранилища.

---

### TC-DRV-017 DELETE /drivers/{id} — блокировка при активном источнике

**Предусловия:** существует источник, использующий этот драйвер

**Шаги:**

1. Отправить DELETE-запрос для такого драйвера

**Ожидаемый результат:** HTTP 409 (или аналогичный код конфликта); ошибка с предупреждением; драйвер не удаляется.

---

## 3. Управление драйверами — Пользовательский интерфейс

### TC-DRV-UI-001 Вкладка «JDBC-драйверы» видна только администратору системы

**Шаги:**

1. Войти как администратор системы — убедиться, что вкладка «JDBC-драйверы» присутствует
2. Войти как администратор тенанта — убедиться, что вкладка отсутствует
3. Войти как разработчик — убедиться, что вкладка отсутствует

**Ожидаемый результат:** вкладка видна только администратору системы.

---

### TC-DRV-UI-002 Отображение пустого состояния

**Предусловия:** в реестре нет драйверов

**Шаги:**

1. Перейти на вкладку «JDBC-драйверы»

**Ожидаемый результат:** таблица отсутствует; отображается только кнопка «Добавить драйвер».

---

### TC-DRV-UI-003 Обязательность поля «Тип»

**Шаги:**

1. Открыть окно «Добавление драйвера»
2. Оставить поле «Тип» пустым, заполнить остальные поля, нажать «Добавить»

**Ожидаемый результат:** под полем «Тип» появляется текст «Поле обязательно для заполнения»; окно не закрывается; драйвер не создаётся.

---

### TC-DRV-UI-004 filepicker допускает только .jar

**Шаги:**

1. Открыть filepicker в окне добавления драйвера

**Ожидаемый результат:** для выбора доступны только файлы с расширением .jar; файлы других форматов недоступны.

---

### TC-DRV-UI-005 Отображение кнопок действий при наведении

**Шаги:**

1. Навести курсор на строку в таблице драйверов

**Ожидаемый результат:** появляются кнопки «Удалить» (иконка корзины) и «Редактировать» (иконка карандаша).

---

### TC-DRV-UI-006 Подтверждение удаления — модальное окно

**Шаги:**

1. Нажать «Удалить» на строке драйвера

**Ожидаемый результат:** открывается модальное окно «Удаление драйвера» с предупредительным текстом и кнопками «Удалить» / «Отмена».

---

### TC-DRV-UI-007 Отмена удаления

**Шаги:**

1. Нажать «Удалить» на строке
2. В модальном окне нажать «Отмена»

**Ожидаемый результат:** окно закрывается; драйвер остаётся в таблице.

---

## 4. Конфигурация подключений — API

### TC-CON-001 POST /connections — успешное создание

**Предусловия:** активный драйвер существует

**Шаги:**

1. Отправить POST-запрос: имя подключения, id драйвера, корректный JDBC URL, логин, пароль (роль: разработчик)

**Ожидаемый результат:** HTTP 201; пароль в БД хранится в зашифрованном виде (прямой запрос к таблице возвращает зашифрованную строку, а не открытый текст).

---

### TC-CON-002 Создание источника с заблокированным/удалённым драйвером

**Шаги:**

1. Отправить POST-запрос, указав id несуществующего или заблокированного драйвера

**Ожидаемый результат:** HTTP 422 (или аналог); ошибка «Драйвер не найден или недоступен».

---

### TC-CON-003 Валидация JDBC URL — запрещённые параметры

**Шаги:**

1. Попытаться создать подключение с URL, содержащим `allowLoadLocalInfile=true`
2. Повторить для `allowMultiQueries=true`, `autoDeserialize=true`, `statementInterceptors`, `connectionInitSql`

**Ожидаемый результат:** HTTP 422; каждый из запрещённых параметров приводит к ошибке; подключение не создаётся.

---

### TC-CON-004 Тестирование подключения — успешный сценарий

**Шаги:**

1. Отправить POST на endpoint тестирования с корректными параметрами (реальная доступная БД)

**Ожидаемый результат:** HTTP 200; ответ содержит признак успеха.

---

### TC-CON-005 Тестирование подключения — неверный пароль

**Шаги:**

1. Отправить POST на endpoint тестирования с неверным паролем

**Ожидаемый результат:** HTTP 200 с ошибкой «Не удалось установить соединение» (либо аналогичный HTTP 4xx с понятным текстом).

---

### TC-CON-006 Тестирование подключения — недоступный хост

**Шаги:**

1. Отправить POST с несуществующим хостом в URL

**Ожидаемый результат:** понятная ошибка «Не удалось установить соединение»; таймаут не подвешивает основной поток.

---

### TC-CON-007 SSL-подключение с валидным сертификатом

**Шаги:**

1. Создать подключение с `activeSSL=true`, загрузить корневой сертификат, запустить тест

**Ожидаемый результат:** соединение успешно установлено по SSL.

---

### TC-CON-008 SSL-подключение с невалидным сертификатом

**Шаги:**

1. Загрузить самоподписанный сертификат, не соответствующий серверу, запустить тест

**Ожидаемый результат:** ошибка «Не удалось установить соединение»; текст ошибки содержит информацию о сертификате.

---

### TC-CON-009 SSH-туннель — успешное подключение

**Шаги:**

1. Создать подключение с `activeSSH=true`, заполнить хост, порт, логин, пароль SSH
2. Нажать «Проверить подключение»

**Ожидаемый результат:** туннель создан, соединение с БД установлено через туннель, тест успешен.

---

### TC-CON-010 SSH-туннель — закрытие после теста

**Шаги:**

1. Запустить тест подключения через SSH
2. Проверить сетевые сокеты на сервере приложения после завершения теста

**Ожидаемый результат:** туннельный сокет закрыт; нет утечки соединений.

---

### TC-CON-011 Шифрование пароля при сохранении

**Шаги:**

1. Создать подключение с паролем `P@ssw0rd`
2. Выполнить прямой SELECT к таблице подключений в БД

**Ожидаемый результат:** в поле пароля хранится зашифрованная строка, не равная `P@ssw0rd`.

---

### TC-CON-012 Частичное обновление — пароль не меняется

**Шаги:**

1. Отправить PATCH-запрос, изменив только имя подключения (поле пароля не передаётся)

**Ожидаемый результат:** пароль в БД остался прежним (зашифрованная строка не изменилась).

---

### TC-CON-013 GET /connections/{id} — пароль не возвращается

**Шаги:**

1. Получить данные подключения через GET

**Ожидаемый результат:** в ответе нет полей `password`, `sshPassword`, `privateKey` с открытыми значениями; поля либо отсутствуют, либо замаскированы.

---

### TC-CON-014 DELETE /connections/{id} — блокировка при активной ETL-задаче

**Предусловия:** запущена ETL-задача, использующая данное подключение

**Шаги:**

1. Отправить DELETE-запрос

**Ожидаемый результат:** HTTP 409; ошибка «Есть активные задачи ETL»; подключение не удаляется.

---

### TC-CON-015 Роль «Администратор тенанта» — изоляция по тенанту

**Шаги:**

1. Войти как администратор тенанта A
2. Попытаться получить или изменить подключение тенанта B через API

**Ожидаемый результат:** HTTP 403 / 404; доступа нет.

---

## 5. Конфигурация подключений — Пользовательский интерфейс

### TC-CON-UI-001 Опция «JDBC» в списке типов источников

**Шаги:**

1. Диспетчер данных → «Создать подключение»
2. Проверить список доступных типов

**Ожидаемый результат:** в списке присутствует опция «JDBC».

---

### TC-CON-UI-002 Обязательность полей «Имя подключения» и «URL»

**Шаги:**

1. Открыть окно нового JDBC-подключения
2. Оставить «Имя подключения» и «URL» пустыми, нажать «Сохранить»

**Ожидаемый результат:** под обоими полями появляется «Поле обязательно для заполнения»; окно не закрывается.

---

### TC-CON-UI-003 Пустой список драйверов — подсказка пользователю

**Предусловия:** в реестре нет ни одного активного драйвера

**Шаги:**

1. Открыть окно нового JDBC-подключения
2. Навести на раскрывающийся список «Драйвер»

**Ожидаемый результат:** список заблокирован; при наведении отображается подсказка «Обратитесь к администратору для загрузки драйверов».

---

### TC-CON-UI-004 Маскировка пароля по умолчанию

**Шаги:**

1. Открыть форму нового подключения
2. Проверить состояние поля «Пароль»

**Ожидаемый результат:** чекбокс «Показать пароль» включён по умолчанию; символы в поле пароля не маскированы при включённом чекбоксе (и маскированы при выключенном).

> **Уточнение:** согласно требованиям, чекбокс «Показать пароль» по умолчанию включён — необходимо убедиться, что поведение соответствует этому требованию.

---

### TC-CON-UI-005 Блок SSL — отображение при включении

**Шаги:**

1. Переключить «Использовать SSL» в положение ON

**Ожидаемый результат:** отображаются поля «Корневой сертификат», «Клиентский сертификат», «Клиентский приватный ключ» с кнопками «Загрузить файл».

---

### TC-CON-UI-006 Загрузка SSL-сертификата — разрешённые форматы

**Шаги:**

1. Включить SSL
2. Нажать «Загрузить файл» для корневого сертификата
3. Проверить доступные расширения в filepicker

**Ожидаемый результат:** доступны только файлы .pem, .crt, .key, .cer.

---

### TC-CON-UI-007 Блок SSH — отображение при включении

**Шаги:**

1. Переключить «Использовать SSH-туннель» в положение ON

**Ожидаемый результат:** отображаются обязательные поля «SSH Хост», «SSH Порт» (по умолчанию 22), «SSH Логин», «SSH Пароль».

---

### TC-CON-UI-008 Успешный тест подключения через UI

**Шаги:**

1. Заполнить форму корректными данными
2. Нажать «Проверить подключение»

**Ожидаемый результат:** всплывающее сообщение «Тест соединения пройден успешно»; форма остаётся открытой.

---

### TC-CON-UI-009 Ошибка теста подключения через UI

**Шаги:**

1. Ввести неверный пароль
2. Нажать «Проверить подключение»

**Ожидаемый результат:** всплывающее сообщение с текстом ошибки с бэкенда; форма не закрывается; введённые данные сохранены.

---

### TC-CON-UI-010 Маскировка пароля в форме редактирования

**Шаги:**

1. Открыть существующее подключение для редактирования

**Ожидаемый результат:** поля пароля и SSH-пароля пустые или замаскированы (значения не отображаются в открытом виде).

---

### TC-CON-UI-011 Иконка JDBC-подключения

**Шаги:**

1. Создать JDBC-подключение и открыть список источников

**Ожидаемый результат:** иконка источника — иконка БД с подписью «JDBC».

---

### TC-CON-UI-012 Кнопка «Назад» — возврат к выбору типа источника

**Шаги:**

1. В форме нового JDBC-подключения нажать «Назад»

**Ожидаемый результат:** происходит переход к окну выбора типа источника; несохранённые данные не остаются.

---

## 6. Загрузка данных (ETL)

### TC-ETL-001 Запуск по расписанию Cron

**Шаги:**

1. Настроить расписание Cron для JDBC-источника (например, каждую минуту)
2. Дождаться наступления времени запуска

**Ожидаемый результат:** задача запускается в запланированное время; в логах зафиксирован старт задачи.

---

### TC-ETL-002 Блокировка параллельного запуска

**Шаги:**

1. Запустить загрузку для источника A
2. Пока загрузка активна, принудительно запустить вторую загрузку для того же источника A

**Ожидаемый результат:** второй запуск отклонён со статусом «Занято»; первая загрузка продолжается.

---

### TC-ETL-003 Снятие блокировки после успешной загрузки

**Шаги:**

1. Дождаться успешного завершения загрузки
2. Попробовать запустить следующую загрузку

**Ожидаемый результат:** блокировка снята; новый запуск проходит успешно.

---

### TC-ETL-004 Снятие блокировки при падении Loader

**Шаги:**

1. Инициировать загрузку
2. Вызвать сбой Loader (имитация exception)
3. Дождаться истечения TTL или срабатывания обработчика ошибок

**Ожидаемый результат:** блокировка автоматически снимается; следующий запуск возможен.

---

### TC-ETL-005 Чтение данных через JDBC (без SSL/SSH)

**Шаги:**

1. Запустить загрузку для JDBC-источника с прямым подключением (без SSL и SSH)

**Ожидаемый результат:** Loader успешно читает данные из внешней БД.

---

### TC-ETL-006 Чтение данных через JDBC + SSH

**Шаги:**

1. Запустить загрузку для JDBC-источника с настроенным SSH-туннелем

**Ожидаемый результат:** туннель открывается до начала чтения, данные читаются корректно, туннель закрывается после завершения.

---

### TC-ETL-007 Запись данных в ClickHouse — маппинг типов

**Шаги:**

1. Запустить загрузку таблицы с разными типами данных (int, varchar, date, decimal)

**Ожидаемый результат:** данные корректно замаппированы на типы ClickHouse; количество строк в целевой таблице совпадает с источником.

---

### TC-ETL-008 Идемпотентность загрузки

**Шаги:**

1. Запустить загрузку с данными из источника
2. Запустить ту же загрузку повторно без изменений в источнике

**Ожидаемый результат:** количество строк в ClickHouse не увеличилось; дубликаты не созданы.

---

### TC-ETL-009 Изоляция ошибки драйвера от основного потока

**Шаги:**

1. Инициировать загрузку с JDBC-источником
2. Вызвать сбой загруженного JDBC-драйвера в процессе загрузки

**Ожидаемый результат:** основной поток работы платформы не падает; ошибка фиксируется только в логах задачи JDBC.

---

### TC-ETL-010 Превью первых 30 строк из JDBC-источника

**Шаги:**

1. Открыть готовый JDBC-источник в диспетчере данных

**Ожидаемый результат:** на фронтенд возвращается до 30 строк из целевой таблицы; SSH/SSL инициализируются и закрываются корректно.

---

## 7. Ролевая модель

### TC-ROLE-001 Администратор системы — полный доступ к драйверам

**Шаги:**

1. Войти как «Администратор системы»
2. Выполнить: загрузка, просмотр, редактирование, удаление драйвера

**Ожидаемый результат:** все операции выполняются успешно.

---

### TC-ROLE-002 Администратор тенанта — нет доступа к управлению драйверами

**Шаги:**

1. Войти как «Администратор тенанта»
2. Попытаться отправить POST /drivers

**Ожидаемый результат:** HTTP 403; вкладка «JDBC-драйверы» в интерфейсе отсутствует.

---

### TC-ROLE-003 Разработчик — нет доступа к управлению драйверами

**Шаги:**

1. Войти как «Разработчик»
2. Попытаться отправить POST /drivers

**Ожидаемый результат:** HTTP 403; вкладка «JDBC-драйверы» в интерфейсе отсутствует.

---

### TC-ROLE-004 Разработчик — создание подключения в своём проекте

**Шаги:**

1. Войти как «Разработчик»
2. Создать JDBC-подключение в своём проекте

**Ожидаемый результат:** подключение создано успешно.

---

### TC-ROLE-005 Разработчик — нет доступа к подключениям чужого проекта

**Шаги:**

1. Войти как «Разработчик A»
2. Попытаться получить, изменить или удалить подключение проекта «Разработчика B»

**Ожидаемый результат:** HTTP 403 / 404; доступ закрыт.

---

### TC-ROLE-006 Администратор тенанта — изоляция по тенанту (источники)

**Шаги:**

1. Войти как «Администратор тенанта A»
2. Запросить список источников

**Ожидаемый результат:** в ответе только источники тенанта A; источники тенанта B не видны.

---

### TC-ROLE-007 Администратор системы — видит все источники всех тенантов

**Шаги:**

1. Войти как «Администратор системы»
2. Запросить список источников

**Ожидаемый результат:** в ответе все источники всех тенантов системы.

---

### TC-ROLE-008 Тестирование подключения — доступно всем трём ролям

**Шаги:**

1. Для каждой из ролей (Администратор системы, Администратор тенанта, Разработчик) отправить POST на endpoint тестирования подключения

**Ожидаемый результат:** все три роли получают HTTP 200 (или ошибку соединения, но не 403).

---

## 8. Логирование

### TC-LOG-001 Логирование результатов валидации драйвера

**Шаги:**

1. Загрузить валидный .jar
2. Загрузить невалидный .jar

**Ожидаемый результат:** в логах системы присутствуют записи о результатах валидации (успех/ошибка) с указанием имени файла и типа нарушения.

---

### TC-LOG-002 Логирование старта и завершения ETL-загрузки

**Шаги:**

1. Запустить и дождаться завершения загрузки через Cron

**Ожидаемый результат:** в логах зафиксированы события: старт задачи, завершение (успех или ошибка), время выполнения.

---

### TC-LOG-003 Логирование ошибок подключения

**Шаги:**

1. Запустить тест подключения с неверными данными

**Ожидаемый результат:** в логах зафиксирована ошибка подключения с деталями (хост, тип ошибки); пароль в логах не отображается в открытом виде.