188 lines
8.8 KiB
Go
188 lines
8.8 KiB
Go
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() вернула данные, хотя в папке не было валидных доноров.")
|
||
}
|
||
})
|
||
}
|