continue write test spec with ai next:/telegram/pool
This commit is contained in:
parent
7a9f4f5cd5
commit
2eecabdbaa
@ -31,6 +31,16 @@
|
|||||||
28. [DELETE /results/{resultId}](#28-delete-resultsresultid)
|
28. [DELETE /results/{resultId}](#28-delete-resultsresultid)
|
||||||
29. [PATCH /result/seen](#29-patch-resultseen)
|
29. [PATCH /result/seen](#29-patch-resultseen)
|
||||||
30. [POST /results/{quizID}/export](#30-post-resultsquizidexport)
|
30. [POST /results/{quizID}/export](#30-post-resultsquizidexport)
|
||||||
|
31. [GET /result/{resultID}](#31-get-resultresultid)
|
||||||
|
32. [POST /statistic/{quizID}/devices](#32-post-statisticquiziddevices)
|
||||||
|
33. [POST /statistic/{quizID}/general](#33-post-statisticquizidgeneral)
|
||||||
|
34. [POST /statistic/{quizID}/questions](#34-post-statisticquizidquestions)
|
||||||
|
35. [POST /statistic](#35-post-statistic)
|
||||||
|
36. [GET /statistics/{quizID}/pipelines](#36-get-statisticsquizidpipelines)
|
||||||
|
37. [GET /telegram/pool](#37-get-telegrampool)
|
||||||
|
38. [POST /telegram/create](#38-post-telegramcreate)
|
||||||
|
39. [DELETE /telegram/{id}](#39-delete-telegramid)
|
||||||
|
40. [POST /telegram/setCode](#40-post-telegramsetcode)
|
||||||
|
|
||||||
## 1. GET /account/get
|
## 1. GET /account/get
|
||||||
|
|
||||||
@ -1797,7 +1807,7 @@
|
|||||||
**Входные данные:**
|
**Входные данные:**
|
||||||
- Метод: POST
|
- Метод: POST
|
||||||
- URL: /question/create
|
- URL: /question/create
|
||||||
- Headers:
|
- Headers:
|
||||||
- Authorization: Bearer {valid_jwt_token}
|
- Authorization: Bearer {valid_jwt_token}
|
||||||
- Content-Type: application/json
|
- Content-Type: application/json
|
||||||
- Тело запроса (согласно схеме `#/components/schemas/QuestionCreateRequest`. Пример для типа "variant"):
|
- Тело запроса (согласно схеме `#/components/schemas/QuestionCreateRequest`. Пример для типа "variant"):
|
||||||
@ -4477,4 +4487,600 @@
|
|||||||
2. Файл Excel формируется корректно, данные соответствуют фильтрам и структуре.
|
2. Файл Excel формируется корректно, данные соответствуют фильтрам и структуре.
|
||||||
3. Обработка всех кодов ошибок (200, 400, 401, 402, 500) соответствует спецификации API.
|
3. Обработка всех кодов ошибок (200, 400, 401, 402, 500) соответствует спецификации API.
|
||||||
4. Операция экспорта безопасна и не влияет на целостность данных.
|
4. Операция экспорта безопасна и не влияет на целостность данных.
|
||||||
5. Логирование и аудит операций экспорта работают корректно.
|
5. Логирование и аудит операций экспорта работают корректно
|
||||||
|
|
||||||
|
## 31. GET /result/{resultID}
|
||||||
|
|
||||||
|
31.1 Описание
|
||||||
|
|
||||||
|
Получение списка ответов (Answer) для указанного resultID. Ответы включают информацию о выбранных пользователем вариантах, устройстве, сессии и мета-данных (например, UTM-метки).
|
||||||
|
|
||||||
|
31.2 Базовые требования
|
||||||
|
|
||||||
|
- Требуется JWT токен авторизации (bearerAuth).
|
||||||
|
- Метод запроса: GET.
|
||||||
|
- Параметр resultID передается в path и является обязательным (string).
|
||||||
|
- В случае успеха (200 OK) возвращает массив объектов Answer.
|
||||||
|
- Поддерживает HTTP коды ответа:
|
||||||
|
- 200 OK — Успешное получение данных.
|
||||||
|
- 400 Bad Request — Некорректный resultID.
|
||||||
|
- 401 Unauthorized — Отсутствие или невалидный токен.
|
||||||
|
- 402 Payment Required — Требуется оплата (например, при превышении квоты).
|
||||||
|
- 500 Internal Server Error — Внутренняя ошибка сервера.
|
||||||
|
|
||||||
|
31.3 Тестовые сценарии
|
||||||
|
|
||||||
|
**31.3.1 Успешное получение списка ответов по resultID**
|
||||||
|
|
||||||
|
_Предусловия:_
|
||||||
|
- Пользователь авторизован.
|
||||||
|
- resultID существует и соответствует завершенному прохождению квиза.
|
||||||
|
- В базе данных имеются связанные ответы.
|
||||||
|
|
||||||
|
_Входные данные:_
|
||||||
|
- Метод: GET
|
||||||
|
- URL: /result/abc123xyz
|
||||||
|
- Headers:
|
||||||
|
- Authorization: Bearer {valid_jwt_token}
|
||||||
|
|
||||||
|
_Ожидаемый результат:_
|
||||||
|
- HTTP Status: 200 OK
|
||||||
|
- Content-Type: application/json
|
||||||
|
- Тело ответа:
|
||||||
|
```json
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"Id": 98765,
|
||||||
|
"content": "{\"selected\": [1, 2]}",
|
||||||
|
"question_id": 321,
|
||||||
|
"QuizId": 101,
|
||||||
|
"Fingerprint": "device-fp-001",
|
||||||
|
"Session": "session-uuid-001",
|
||||||
|
"Result": true,
|
||||||
|
"CreatedAt": "2024-12-01T12:00:00Z",
|
||||||
|
"new": false,
|
||||||
|
"Deleted": false,
|
||||||
|
"Email": "user@example.com",
|
||||||
|
"DeviceType": "mobile",
|
||||||
|
"Device": "iPhone 13",
|
||||||
|
"Browser": "Safari",
|
||||||
|
"IP": "192.168.1.10",
|
||||||
|
"OS": "iOS 17",
|
||||||
|
"Start": false,
|
||||||
|
"Utm": {
|
||||||
|
"utm_source": "newsletter",
|
||||||
|
"utm_campaign": "winter_sale"
|
||||||
|
},
|
||||||
|
"Version": 3
|
||||||
|
}
|
||||||
|
]
|
||||||
|
```
|
||||||
|
_Проверки:_
|
||||||
|
- Ответ — JSON-массив.
|
||||||
|
- Каждый элемент соответствует объекту Answer по схеме.
|
||||||
|
- Указан корректный resultID, и все ответы относятся к нему.
|
||||||
|
- Присутствуют все поля, включая Session, Device, IP, content, Utm и др.
|
||||||
|
- В поле content корректно сериализован JSON, соответствующий типу вопроса.
|
||||||
|
- Поля Deleted, Start, Result, new — логические, отражают статус ответа.
|
||||||
|
- Если Utm присутствует, он представлен как объект с произвольными ключами и строковыми значениями.
|
||||||
|
- Убедиться в правильности формата поля CreatedAt (RFC 3339).
|
||||||
|
|
||||||
|
**31.3.2 Проверка авторизации**
|
||||||
|
|
||||||
|
_Сценарий 2.1: Отсутствие токена_
|
||||||
|
- Headers: отсутствует Authorization
|
||||||
|
- Ожидаемый результат: 401 Unauthorized
|
||||||
|
|
||||||
|
_Сценарий 2.2: Невалидный токен_
|
||||||
|
- Headers: Authorization: Bearer invalid_token
|
||||||
|
- Ожидаемый результат: 401 Unauthorized
|
||||||
|
|
||||||
|
**31.3.3 Проверка обработки ошибок (400, 402, 500)**
|
||||||
|
|
||||||
|
_Сценарий 3.1: Некорректный resultID (например, пустая строка или недопустимый UUID)_
|
||||||
|
- URL: /result/
|
||||||
|
- Ожидаемый результат: 400 Bad Request
|
||||||
|
|
||||||
|
_Сценарий 3.2: resultID не существует_
|
||||||
|
- URL: /result/nonexistent123
|
||||||
|
- Ожидаемый результат: 200 OK, но пустой массив []
|
||||||
|
|
||||||
|
_Сценарий 3.3: Требуется оплата_
|
||||||
|
- Предусловия: Квота использования исчерпана или аккаунт не активен.
|
||||||
|
- Ожидаемый результат: 402 Payment Required
|
||||||
|
|
||||||
|
_Сценарий 3.4: Внутренняя ошибка сервера_
|
||||||
|
- Предусловия: Имитация сбоя на уровне БД
|
||||||
|
- Ожидаемый результат: 500 Internal Server Error
|
||||||
|
|
||||||
|
31.4 Особые моменты для тестирования
|
||||||
|
|
||||||
|
- Структура Answer: Проверить наличие всех полей, особенно content, Utm, Email, DeviceType, Browser.
|
||||||
|
- Массив ответов может быть пустым: Проверить поведение при отсутствии ответов.
|
||||||
|
- Согласованность данных: Все ответы должны относиться к одному resultID.
|
||||||
|
- UTM-метки: Должны корректно отображаться и соответствовать параметрам в момент начала прохождения квиза.
|
||||||
|
- Безопасность: Нельзя получить данные по resultID, если токен не авторизован.
|
||||||
|
- Поля с типом boolean: Проверить логическую корректность (Result, Start, Deleted, new).
|
||||||
|
- Формат времени: CreatedAt должен быть корректно сериализован в формате date-time.
|
||||||
|
|
||||||
|
31.5 Критерии приемки
|
||||||
|
|
||||||
|
- Эндпоинт возвращает ответы, соответствующие resultID.
|
||||||
|
- Все поля объекта Answer соответствуют описанию схемы.
|
||||||
|
- Работает авторизация: без токена — 401, с невалидным токеном — 401.
|
||||||
|
- Ошибки при недопустимом resultID возвращают 400, при проблемах оплаты — 402.
|
||||||
|
- При пустом результате возвращается пустой JSON-массив.
|
||||||
|
- Внутренние сбои сервера корректно обрабатываются с кодом 500.
|
||||||
|
- UTM-данные корректно отображаются, если присутствуют.
|
||||||
|
- Проверка структуры и типов данных пройдена.
|
||||||
|
- Все поля имеют предсказуемую структуру, включая вложенные объекты.
|
||||||
|
|
||||||
|
## 32. POST /statistic/{quizID}/devices
|
||||||
|
|
||||||
|
32.1 Описание
|
||||||
|
|
||||||
|
Получение статистики по устройствам, операционным системам и браузерам, использованным участниками при прохождении квиза с указанным quizID. Статистика рассчитывается на основе ответов, у которых res = true (итоговые ответы).
|
||||||
|
|
||||||
|
32.2 Базовые требования
|
||||||
|
|
||||||
|
- Требуется JWT токен авторизации (bearerAuth).
|
||||||
|
- Метод запроса: POST
|
||||||
|
- Путь должен содержать обязательный параметр quizID (string).
|
||||||
|
- Тело запроса должно соответствовать схеме DeviceStatRequest:
|
||||||
|
- From — начало временного диапазона (timestamp, опционально)
|
||||||
|
- To — конец временного диапазона (timestamp, опционально)
|
||||||
|
- В случае успеха (200 OK) возвращается объект, содержащий три словаря с процентным распределением:
|
||||||
|
- Device, OS, Browser
|
||||||
|
- Поддерживаемые коды ответа:
|
||||||
|
- 200 OK
|
||||||
|
- 400 Bad Request (например, неверный формат дат или параметров)
|
||||||
|
- 401 Unauthorized (отсутствие или невалидный токен)
|
||||||
|
- 500 Internal Server Error (непредвиденная ошибка на сервере)
|
||||||
|
|
||||||
|
32.3 Тестовые сценарии
|
||||||
|
|
||||||
|
**32.3.1 Успешное получение статистики по устройствам**
|
||||||
|
|
||||||
|
_Предусловия:_
|
||||||
|
- Пользователь авторизован.
|
||||||
|
- quizID существует.
|
||||||
|
- В базе есть ответы с res=true в указанном диапазоне дат или без фильтрации по времени.
|
||||||
|
|
||||||
|
_Входные данные:_
|
||||||
|
- Метод: POST
|
||||||
|
- URL: /statistic/12345/devices
|
||||||
|
- Headers:
|
||||||
|
- Authorization: Bearer {valid_jwt_token}
|
||||||
|
- Content-Type: application/json
|
||||||
|
- Тело запроса:
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"From": 1700000000,
|
||||||
|
"To": 1709999999
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
_Ожидаемый результат:_
|
||||||
|
- HTTP Status: 200 OK
|
||||||
|
- Content-Type: application/json
|
||||||
|
- Тело ответа:
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"devices": [
|
||||||
|
{
|
||||||
|
"Device": {
|
||||||
|
"mobile": 65.5,
|
||||||
|
"desktop": 30.2,
|
||||||
|
"tablet": 4.3
|
||||||
|
},
|
||||||
|
"OS": {
|
||||||
|
"iOS": 40.1,
|
||||||
|
"Android": 25.4,
|
||||||
|
"Windows": 20.0,
|
||||||
|
"macOS": 14.5
|
||||||
|
},
|
||||||
|
"Browser": {
|
||||||
|
"Chrome": 60.0,
|
||||||
|
"Safari": 25.0,
|
||||||
|
"Firefox": 10.0,
|
||||||
|
"Edge": 5.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
_Проверки:_
|
||||||
|
- Код ответа — 200 OK.
|
||||||
|
- Поле devices — массив длиной 1, содержащий объект.
|
||||||
|
- Все вложенные объекты Device, OS, Browser представлены как словари (object) с ключами-строками и значениями с типом float.
|
||||||
|
- Все значения — проценты (0–100), в сумме могут (но не обязаны) давать 100 по каждому разделу.
|
||||||
|
- Устройства, ОС и браузеры перечислены корректно, названия в формате строк (например, "iOS", "Chrome").
|
||||||
|
- При наличии фильтра From и To, данные учитываются только в этом диапазоне.
|
||||||
|
- Если ответов с res=true нет, вернётся пустые объекты или объекты с нулями:
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"devices": [
|
||||||
|
{
|
||||||
|
"Device": {},
|
||||||
|
"OS": {},
|
||||||
|
"Browser": {}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**32.3.2 Без временного диапазона (все данные)**
|
||||||
|
|
||||||
|
_Входные данные:_
|
||||||
|
```json
|
||||||
|
{}
|
||||||
|
```
|
||||||
|
_Ожидаемый результат:_
|
||||||
|
- HTTP Status: 200 OK
|
||||||
|
- Возвращается статистика по всем ответам res=true без фильтрации по времени.
|
||||||
|
|
||||||
|
**32.3.3 Проверка авторизации**
|
||||||
|
|
||||||
|
_Сценарий 3.1: Отсутствие токена_
|
||||||
|
- Headers: без Authorization
|
||||||
|
- Ожидаемый результат: 401 Unauthorized
|
||||||
|
|
||||||
|
_Сценарий 3.2: Невалидный токен_
|
||||||
|
- Headers: Authorization: Bearer invalid_token
|
||||||
|
- Ожидаемый результат: 401 Unauthorized
|
||||||
|
|
||||||
|
**32.3.4 Проверка валидации (400 Bad Request)**
|
||||||
|
|
||||||
|
_Сценарий 4.1: Некорректный формат timestamp_
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"From": "not_a_timestamp",
|
||||||
|
"To": 1700000000
|
||||||
|
}
|
||||||
|
```
|
||||||
|
_Сценарий 4.2: quizID некорректного формата_
|
||||||
|
- URL: /statistic/!!invalid/devices
|
||||||
|
|
||||||
|
_Ожидаемый результат (для обоих):_
|
||||||
|
- HTTP Status: 400 Bad Request
|
||||||
|
- Сообщение об ошибке указывает на некорректный формат входных данных.
|
||||||
|
|
||||||
|
**32.3.5 Внутренняя ошибка сервера**
|
||||||
|
|
||||||
|
_Сценарий 5.1: Ошибка чтения из базы_
|
||||||
|
- Эмуляция сбоя на уровне БД.
|
||||||
|
|
||||||
|
_Ожидаемый результат:_
|
||||||
|
- HTTP Status: 500 Internal Server Error
|
||||||
|
|
||||||
|
32.4 Особые моменты для тестирования
|
||||||
|
|
||||||
|
- Корректность расчетов: Проверить, что доли рассчитаны правильно (например, из 100 ответов: 60 мобильных → 60%).
|
||||||
|
- Диапазон значений: Убедиться, что значения в процентах, тип float, в пределах 0–100.
|
||||||
|
- Сумма значений: Проверить, что сумма по каждой категории не превышает 100 (но допускается < 100 из-за округления или пропущенных значений).
|
||||||
|
- Поведение при отсутствии данных: Убедиться, что возвращается пустая статистика, а не ошибка.
|
||||||
|
- Большие объемы данных: Проверить производительность и корректность при большом числе ответов.
|
||||||
|
- Безопасность: Нельзя получить статистику без авторизации.
|
||||||
|
- Точность по времени: Проверить корректную фильтрацию по From и To, включая граничные значения.
|
||||||
|
|
||||||
|
32.5 Критерии приемки
|
||||||
|
|
||||||
|
- Все тестовые сценарии из раздела 32.3 выполняются успешно.
|
||||||
|
- Результаты статистики корректны по значениям и структуре.
|
||||||
|
- Поля Device, OS, Browser соответствуют требованиям по типам и форматам.
|
||||||
|
- Диапазон дат фильтрует данные правильно.
|
||||||
|
- Ошибки в запросах возвращают 400, отсутствие авторизации — 401.
|
||||||
|
- Сервер обрабатывает сбои корректно с кодом 500.
|
||||||
|
|
||||||
|
## 33. POST /statistic/{quizID}/general
|
||||||
|
|
||||||
|
33.1 Описание
|
||||||
|
|
||||||
|
Получение общей статистики по квизу с указанным quizID, включая:
|
||||||
|
- количество открытий (Open)
|
||||||
|
- количество завершений (Result)
|
||||||
|
- среднее время прохождения (AvTime)
|
||||||
|
- конверсию (Conversion)
|
||||||
|
|
||||||
|
Все значения сгруппированы по дате/временным меткам. Поддерживается фильтрация по диапазону времени с помощью полей From и To.
|
||||||
|
|
||||||
|
33.2 Базовые требования
|
||||||
|
|
||||||
|
- Метод: POST
|
||||||
|
- Аутентификация: bearerAuth (JWT токен обязателен)
|
||||||
|
- Параметры пути:
|
||||||
|
- quizID — идентификатор квиза (обязателен, string)
|
||||||
|
- Тело запроса: JSON по схеме DeviceStatRequest:
|
||||||
|
- From — начало диапазона (timestamp)
|
||||||
|
- To — конец диапазона (timestamp)
|
||||||
|
- Код ответа 200 OK содержит объект с полями:
|
||||||
|
- Open, Result, AvTime, Conversion — объекты вида { timestamp: value }
|
||||||
|
|
||||||
|
33.3 Тестовые сценарии
|
||||||
|
|
||||||
|
**33.3.1 Успешное получение общей статистики**
|
||||||
|
|
||||||
|
_Предусловия:_
|
||||||
|
- Пользователь авторизован
|
||||||
|
- Существуют записи статистики для указанного quizID
|
||||||
|
|
||||||
|
_Входные данные:_
|
||||||
|
- URL: /statistic/12345/general
|
||||||
|
- Headers:
|
||||||
|
- Authorization: Bearer {valid_token}
|
||||||
|
- Content-Type: application/json
|
||||||
|
- Тело:
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"From": 1700000000,
|
||||||
|
"To": 1709999999
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
_Ожидаемый результат:_
|
||||||
|
- Код: 200 OK
|
||||||
|
- Content-Type: application/json
|
||||||
|
- Тело ответа:
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"Open": {
|
||||||
|
"1700010000": 150,
|
||||||
|
"1700020000": 175
|
||||||
|
},
|
||||||
|
"Result": {
|
||||||
|
"1700010000": 80,
|
||||||
|
"1700020000": 90
|
||||||
|
},
|
||||||
|
"AvTime": {
|
||||||
|
"1700010000": 45000,
|
||||||
|
"1700020000": 48000
|
||||||
|
},
|
||||||
|
"Conversion": {
|
||||||
|
"1700010000": 53,
|
||||||
|
"1700020000": 51
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
_Проверки:_
|
||||||
|
- Код — 200 OK
|
||||||
|
- Все поля (Open, Result, AvTime, Conversion) — объекты (object)
|
||||||
|
- Ключи — строки, представляющие timestamp (можно дополнительно валидировать диапазон)
|
||||||
|
- Значения:
|
||||||
|
- Open и Result — целые числа (uint64)
|
||||||
|
- AvTime — среднее время в миллисекундах (uint64)
|
||||||
|
- Conversion — проценты (0–100), округленные целые числа (uint64)
|
||||||
|
- Даты фильтруются по диапазону From–To
|
||||||
|
|
||||||
|
**33.3.2 Без временного диапазона (все данные)**
|
||||||
|
|
||||||
|
_Вход:_
|
||||||
|
```json
|
||||||
|
{}
|
||||||
|
```
|
||||||
|
_Ожидаемый результат:_
|
||||||
|
- Код: 200 OK
|
||||||
|
- Данные по всей доступной статистике
|
||||||
|
|
||||||
|
**33.3.3 Нет данных в указанном диапазоне**
|
||||||
|
|
||||||
|
_Вход:_
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"From": 1500000000,
|
||||||
|
"To": 1500003600
|
||||||
|
}
|
||||||
|
```
|
||||||
|
_Ожидаемый результат:_
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"Open": {},
|
||||||
|
"Result": {},
|
||||||
|
"AvTime": {},
|
||||||
|
"Conversion": {}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**33.3.4 Ошибки авторизации**
|
||||||
|
|
||||||
|
_Сценарий 1: Без токена_
|
||||||
|
- Headers: отсутствует Authorization
|
||||||
|
- Ответ: 401 Unauthorized
|
||||||
|
|
||||||
|
_Сценарий 2: Невалидный токен_
|
||||||
|
- Headers: Authorization: Bearer invalid_token
|
||||||
|
- Ответ: 401 Unauthorized
|
||||||
|
|
||||||
|
**33.3.5 Ошибка валидации (400 Bad Request)**
|
||||||
|
|
||||||
|
_Примеры:_
|
||||||
|
- From или To не число:
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"From": "invalid",
|
||||||
|
"To": 1700000000
|
||||||
|
}
|
||||||
|
```
|
||||||
|
- quizID содержит запрещённые символы:
|
||||||
|
/statistic/!!bad_id/general
|
||||||
|
|
||||||
|
_Ожидаемый результат:_
|
||||||
|
- Код: 400 Bad Request
|
||||||
|
|
||||||
|
**33.3.6 Внутренняя ошибка сервера**
|
||||||
|
|
||||||
|
_Например:_
|
||||||
|
- Ошибка доступа к базе
|
||||||
|
- Исключение во время обработки статистики
|
||||||
|
|
||||||
|
_Ожидаемый результат:_
|
||||||
|
- Код: 500 Internal Server Error
|
||||||
|
|
||||||
|
33.4 Особенности и проверки
|
||||||
|
|
||||||
|
| Поле | Описание | Проверки |
|
||||||
|
|-----------|-----------------------------------------------|--------------------------------------------------------|
|
||||||
|
| Open | Количество открытий квиза по timestamp'ам | timestamp: uint64 |
|
||||||
|
| Result | Кол-во завершений (ответов с res=true) | timestamp: uint64 |
|
||||||
|
| AvTime | Среднее время прохождения (в мс) | Значения > 0, логично по отношению к Result |
|
||||||
|
| Conversion| Конверсия: Result / Open * 100 округлённое | От 0 до 100, должно коррелировать с Open и Result |
|
||||||
|
|
||||||
|
33.5 Критерии приёмки
|
||||||
|
|
||||||
|
- Авторизация обязательна
|
||||||
|
- Корректный диапазон по времени работает
|
||||||
|
- Формат timestamp и значений верный
|
||||||
|
- Конверсия адекватна (Open > 0)
|
||||||
|
- Ошибки корректно обрабатываются (400, 401, 500)
|
||||||
|
- Пустая статистика не вызывает ошибок
|
||||||
|
- Статистика агрегируется по временным ключам (по дню/часу, в зависимости от реализации)
|
||||||
|
|
||||||
|
34. POST /statistic/{quizID}/questions
|
||||||
|
|
||||||
|
34.1 Описание
|
||||||
|
|
||||||
|
Запрос возвращает подробную статистику по вопросам квиза, включая:
|
||||||
|
- Метрики воронки (Funnel)
|
||||||
|
- Подробные данные воронки (FunnelData)
|
||||||
|
- Процент завершений по каждому вопросу (Results)
|
||||||
|
- Распределение ответов по каждому вопросу (Questions)
|
||||||
|
|
||||||
|
Фильтрация осуществляется по диапазону времени (From – To), и применяется только к ответам с Result=true.
|
||||||
|
|
||||||
|
34.2 Параметры
|
||||||
|
|
||||||
|
- Метод: POST
|
||||||
|
- Аутентификация: bearerAuth
|
||||||
|
- Путь: /statistic/{quizID}/questions
|
||||||
|
- quizID — string (обязателен)
|
||||||
|
- Тело запроса: JSON по схеме DeviceStatRequest
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"From": 1700000000,
|
||||||
|
"To": 1709999999
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
34.3 Описание структуры ответа (QuestionStat)
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"Funnel": [95.5, 78.3, 60.1],
|
||||||
|
"FunnelData": [1200, 900, 750, 600],
|
||||||
|
"Results": {
|
||||||
|
"Как вы оцениваете наш сервис?": 87.5,
|
||||||
|
"Сколько вам лет?": 92.0
|
||||||
|
},
|
||||||
|
"Questions": {
|
||||||
|
"Как вы оцениваете наш сервис?": {
|
||||||
|
"Отлично": 65.2,
|
||||||
|
"Хорошо": 25.3,
|
||||||
|
"Удовлетворительно": 9.5
|
||||||
|
},
|
||||||
|
"Сколько вам лет?": {
|
||||||
|
"18-24": 40.0,
|
||||||
|
"25-34": 30.0,
|
||||||
|
"35-44": 20.0,
|
||||||
|
"45+": 10.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
| Поле | Тип | Описание |
|
||||||
|
|-----------|----------|-------------------------------------------------------|
|
||||||
|
| Funnel | float[] | Метрики воронки (максимум 3 значения) — в процентах |
|
||||||
|
| FunnelData| float[] | Дополнительные данные воронки (максимум 4 знач.) |
|
||||||
|
| Results | object | Карта вопрос: % завершивших |
|
||||||
|
| Questions | object | Карта вопрос: { ответ: % распределения } |
|
||||||
|
|
||||||
|
34.4 Тест-кейсы
|
||||||
|
|
||||||
|
**✅ 34.4.1 Успешное получение статистики по вопросам**
|
||||||
|
|
||||||
|
_Вход:_
|
||||||
|
|
||||||
|
POST /statistic/12345/questions
|
||||||
|
Authorization: Bearer valid_token
|
||||||
|
Content-Type: application/json
|
||||||
|
|
||||||
|
Тело:
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"From": 1700000000,
|
||||||
|
"To": 1709999999
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
_Ожидаемый ответ:_
|
||||||
|
- Код: 200 OK
|
||||||
|
- Тип: application/json
|
||||||
|
- Структура: массив объектов QuestionStat (в большинстве случаев массив из 1 элемента)
|
||||||
|
|
||||||
|
_Проверки:_
|
||||||
|
- Funnel.length <= 3, FunnelData.length <= 4
|
||||||
|
- Значения — float
|
||||||
|
- Results: ключи — строки, значения — float (0.0 – 100.0)
|
||||||
|
- Questions: ключи — строки (вопросы), значения — объекты с ответ: % (в пределах 0.0–100.0)
|
||||||
|
- Сумма распределения по каждому вопросу ≈ 100 (можно ±0.1)
|
||||||
|
|
||||||
|
**✅ 34.4.2 Пустая статистика по диапазону**
|
||||||
|
|
||||||
|
_Тело запроса:_
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"From": 1500000000,
|
||||||
|
"To": 1500003600
|
||||||
|
}
|
||||||
|
```
|
||||||
|
_Ожидаемый результат:_
|
||||||
|
```json
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"Funnel": [],
|
||||||
|
"FunnelData": [],
|
||||||
|
"Results": {},
|
||||||
|
"Questions": {}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
```
|
||||||
|
|
||||||
|
**🔒 34.4.3 Ошибка авторизации**
|
||||||
|
|
||||||
|
_Сценарии:_
|
||||||
|
- Без токена → 401 Unauthorized
|
||||||
|
- С невалидным токеном → 401 Unauthorized
|
||||||
|
|
||||||
|
**⚠️ 34.4.4 Ошибка валидации запроса**
|
||||||
|
|
||||||
|
_Примеры:_
|
||||||
|
- From и To не числа:
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"From": "abc",
|
||||||
|
"To": 123
|
||||||
|
}
|
||||||
|
```
|
||||||
|
- quizID некорректен:
|
||||||
|
/statistic/<>/questions
|
||||||
|
|
||||||
|
_Ожидаемый результат:_ 400 Bad Request
|
||||||
|
|
||||||
|
**💥 34.4.5 Внутренняя ошибка**
|
||||||
|
|
||||||
|
_Примеры:_
|
||||||
|
- Ошибка агрегации данных
|
||||||
|
- Сбой базы
|
||||||
|
|
||||||
|
_Ожидаемый результат:_ 500 Internal Server Error
|
||||||
|
|
||||||
|
34.5 Критерии приёмки
|
||||||
|
|
||||||
|
| Условие | Проверка |
|
||||||
|
|-------------------------------------------|----------|
|
||||||
|
| ✅ Авторизация обязательна | Да |
|
||||||
|
| ✅ Статистика корректно фильтруется по времени | Да |
|
||||||
|
| ✅ Пустые данные не вызывают ошибок | Да |
|
||||||
|
| ✅ Значения — в допустимых диапазонах | Да |
|
||||||
|
| ✅ Все поля валидируются | Да |
|
Loading…
Reference in New Issue
Block a user