Files
shtrihscanner/main_test.go
SERTY 6c3950953e 0.1.3-prod
reduce timeouts
added tests and mock interface
2025-08-22 03:38:57 +03:00

188 lines
8.8 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package main
import (
"encoding/json"
"os"
"path/filepath"
"shtrih-kkt/pkg/shtrih"
"testing"
)
// loadCanonicalKKTData загружает эталонные данные ККТ из файла для тестов.
// Путь к файлу указывается относительно корня проекта.
func loadCanonicalKKTData(t *testing.T, path string) *shtrih.FiscalInfo {
data, err := os.ReadFile(path)
if err != nil {
t.Fatalf("Критическая ошибка: не удалось прочитать канонический файл данных '%s': %v", path, err)
}
var info shtrih.FiscalInfo
if err := json.Unmarshal(data, &info); err != nil {
t.Fatalf("Критическая ошибка: не удалось распарсить JSON из канонического файла '%s': %v", path, err)
}
return &info
}
// TestProcessDevices_NewFileFromDonor проверяет сценарий, когда для ККТ еще нет
// файла, но есть файл-донор с данными о рабочей станции.
func TestProcessDevices_NewFileFromDonor(t *testing.T) {
// --- Arrange (Подготовка) ---
// 1. Создаем временную директорию для теста, чтобы не засорять реальную папку `date`.
tempDir := t.TempDir()
originalOutputDir := outputDir
outputDir = tempDir
defer func() { outputDir = originalOutputDir }()
// 2. Загружаем канонические данные для мок-драйвера из файла.
// Этот файл должен быть создан заранее и помещен в pkg/shtrih/testdata/
mockKKTData := loadCanonicalKKTData(t, "pkg/shtrih/testdata/canonical_kkt_data.json")
// 3. Создаем файл-донор с уникальными данными о рабочей станции во временной папке.
donorData := map[string]interface{}{
"hostname": "DONOR-PC",
"teamviewer_id": "999888777",
"vc": "3.0-donor-test",
}
donorBytes, _ := json.Marshal(donorData)
donorFilePath := filepath.Join(tempDir, "donor.json")
if err := os.WriteFile(donorFilePath, donorBytes, 0644); err != nil {
t.Fatalf("Не удалось создать тестовый файл-донор: %v", err)
}
// 4. Создаем "фабрику", которая вернет мок-драйвер с нашими каноническими данными.
mockDriverFactory := func(config shtrih.Config) shtrih.Driver {
return shtrih.NewMockDriver(mockKKTData, nil, nil)
}
// 5. Готовим входные данные для processDevices.
testConfigs := []shtrih.Config{{ConnectionType: 6, IPAddress: "127.0.0.1"}}
// --- Act (Действие) ---
processDevices(testConfigs, mockDriverFactory)
// --- Assert (Проверка) ---
// 1. Проверяем, что был создан правильный JSON-файл.
expectedFileName := mockKKTData.SerialNumber + ".json"
resultFilePath := filepath.Join(tempDir, expectedFileName)
if _, err := os.Stat(resultFilePath); os.IsNotExist(err) {
t.Fatalf("Ожидалось, что будет создан файл '%s', но он не найден.", resultFilePath)
}
// 2. Читаем созданный файл и проверяем его содержимое.
resultBytes, err := os.ReadFile(resultFilePath)
if err != nil {
t.Fatalf("Не удалось прочитать результирующий файл '%s': %v", resultFilePath, err)
}
var resultMap map[string]interface{}
if err := json.Unmarshal(resultBytes, &resultMap); err != nil {
t.Fatalf("Не удалось распарсить JSON из результирующего файла: %v", err)
}
// 3. Проверяем, что данные из ККТ и донора корректно слились.
// Проверка поля от ККТ.
if resultMap["modelName"] != mockKKTData.ModelName {
t.Errorf("Поле 'modelName' неверно. Ожидалось '%s', получено '%v'", mockKKTData.ModelName, resultMap["modelName"])
}
// Проверка полей от донора.
if resultMap["hostname"] != donorData["hostname"] {
t.Errorf("Поле 'hostname' из донора не было добавлено. Ожидалось '%s', получено '%v'", donorData["hostname"], resultMap["hostname"])
}
if resultMap["vc"] != donorData["vc"] {
t.Errorf("Поле 'vc' из донора не было добавлено. Ожидалось '%s', получено '%v'", donorData["vc"], resultMap["vc"])
}
// Проверка автоматически сгенерированных полей времени.
if _, ok := resultMap["current_time"]; !ok {
t.Error("Отсутствует обязательное поле 'current_time'.")
}
if _, ok := resultMap["v_time"]; !ok {
t.Error("Отсутствует обязательное поле 'v_time'.")
}
}
// TestFindSourceWorkstationData_FileHandling проверяет непосредственно логику
// поиска и чтения донор-файла в смоделированной файловой структуре.
func TestFindSourceWorkstationData_FileHandling(t *testing.T) {
// --- Сценарий 1: В папке /date есть правильный донор-файл ---
t.Run("when valid donor file exists", func(t *testing.T) {
// Arrange: Готовим файловую систему
tempDir := t.TempDir()
originalOutputDir := outputDir
outputDir = tempDir // Указываем, что наша папка "date" находится во временной директории
defer func() { outputDir = originalOutputDir }()
// Создаем донор-файл с уникальными данными для проверки
donorData := map[string]interface{}{
"hostname": "REAL-DONOR-PC",
"vc": "v_from_real_file",
}
donorBytes, _ := json.Marshal(donorData)
if err := os.WriteFile(filepath.Join(tempDir, "donor_to_find.json"), donorBytes, 0644); err != nil {
t.Fatalf("Не удалось создать тестовый файл-донор: %v", err)
}
// Создаем "файл-ловушку" от другого ККТ, который должен быть проигнорирован
kktTrapData := map[string]interface{}{
"modelName": "SOME-OTHER-KKT",
"serialNumber": "TRAP000001",
"hostname": "FAKE-HOSTNAME",
}
trapBytes, _ := json.Marshal(kktTrapData)
if err := os.WriteFile(filepath.Join(tempDir, "000001.json"), trapBytes, 0644); err != nil {
t.Fatalf("Не удалось создать файл-ловушку: %v", err)
}
// Act: Вызываем тестируемую функцию
resultMap := findSourceWorkstationData()
// Assert: Проверяем результат
if resultMap == nil {
t.Fatal("findSourceWorkstationData() вернула nil, хотя ожидались данные из донора.")
}
if resultMap["hostname"] != "REAL-DONOR-PC" {
t.Errorf("Hostname из донора прочитан неверно. Ожидалось 'REAL-DONOR-PC', получено '%v'", resultMap["hostname"])
}
if resultMap["vc"] != "v_from_real_file" {
t.Errorf("Поле 'vc' из донора прочитано неверно. Ожидалось 'v_from_real_file', получено '%v'", resultMap["vc"])
}
})
// --- Сценарий 2: В папке /date нет подходящих файлов ---
t.Run("when no valid donor file exists", func(t *testing.T) {
// Arrange: Готовим файловую систему
tempDir := t.TempDir()
originalOutputDir := outputDir
outputDir = tempDir
defer func() { outputDir = originalOutputDir }()
// Создаем только "файл-ловушку", который не должен считаться донором
kktTrapData := map[string]interface{}{
"modelName": "SOME-OTHER-KKT",
"serialNumber": "TRAP000001",
"hostname": "FAKE-HOSTNAME",
}
trapBytes, _ := json.Marshal(kktTrapData)
if err := os.WriteFile(filepath.Join(tempDir, "000001.json"), trapBytes, 0644); err != nil {
t.Fatalf("Не удалось создать файл-ловушку: %v", err)
}
// Создаем текстовый файл, который тоже должен быть проигнорирован
if err := os.WriteFile(filepath.Join(tempDir, "readme.txt"), []byte("info"), 0644); err != nil {
t.Fatalf("Не удалось создать текстовый файл: %v", err)
}
// Act: Вызываем тестируемую функцию
resultMap := findSourceWorkstationData()
// Assert: Проверяем, что функция ничего не нашла
if resultMap != nil {
t.Fatal("findSourceWorkstationData() вернула данные, хотя в папке не было валидных доноров.")
}
})
}