0.1.3-prod
reduce timeouts added tests and mock interface
This commit is contained in:
187
main_test.go
Normal file
187
main_test.go
Normal file
@@ -0,0 +1,187 @@
|
||||
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() вернула данные, хотя в папке не было валидных доноров.")
|
||||
}
|
||||
})
|
||||
}
|
||||
Reference in New Issue
Block a user