111 lines
5.7 KiB
Dart
111 lines
5.7 KiB
Dart
import 'dart:typed_data';
|
|
|
|
import 'package:excel/excel.dart';
|
|
import 'package:flutter_test/flutter_test.dart';
|
|
import 'package:lanebow/utils/event_excel_parser.dart';
|
|
|
|
void main() {
|
|
group('EventExcelParser.parseExcelBytes', () {
|
|
test('유효한 행과 무효 행을 올바르게 분리하고 필수 필드 처리', () {
|
|
// Arrange: 엑셀 생성 및 헤더/데이터 작성
|
|
final excel = Excel.createExcel();
|
|
final sheet = excel.sheets.keys.first;
|
|
|
|
// 헤더 행(title, startDate, endDate, location, status, type, maxParticipants)
|
|
excel.updateCell(sheet, CellIndex.indexByColumnRow(columnIndex: 0, rowIndex: 0), TextCellValue('title'));
|
|
excel.updateCell(sheet, CellIndex.indexByColumnRow(columnIndex: 1, rowIndex: 0), TextCellValue('startDate'));
|
|
excel.updateCell(sheet, CellIndex.indexByColumnRow(columnIndex: 2, rowIndex: 0), TextCellValue('endDate'));
|
|
excel.updateCell(sheet, CellIndex.indexByColumnRow(columnIndex: 3, rowIndex: 0), TextCellValue('location'));
|
|
excel.updateCell(sheet, CellIndex.indexByColumnRow(columnIndex: 4, rowIndex: 0), TextCellValue('status'));
|
|
excel.updateCell(sheet, CellIndex.indexByColumnRow(columnIndex: 5, rowIndex: 0), TextCellValue('type'));
|
|
excel.updateCell(sheet, CellIndex.indexByColumnRow(columnIndex: 6, rowIndex: 0), TextCellValue('maxParticipants'));
|
|
|
|
// 유효한 행: 날짜는 문자열, location은 빈 문자열(-> null)
|
|
excel.updateCell(sheet, CellIndex.indexByColumnRow(columnIndex: 0, rowIndex: 1), TextCellValue('Monthly Match'));
|
|
excel.updateCell(sheet, CellIndex.indexByColumnRow(columnIndex: 1, rowIndex: 1), TextCellValue('2025-08-01'));
|
|
excel.updateCell(sheet, CellIndex.indexByColumnRow(columnIndex: 2, rowIndex: 1), TextCellValue('2025-08-02'));
|
|
excel.updateCell(sheet, CellIndex.indexByColumnRow(columnIndex: 3, rowIndex: 1), TextCellValue(''));
|
|
excel.updateCell(sheet, CellIndex.indexByColumnRow(columnIndex: 4, rowIndex: 1), TextCellValue('active'));
|
|
excel.updateCell(sheet, CellIndex.indexByColumnRow(columnIndex: 5, rowIndex: 1), TextCellValue('regular'));
|
|
excel.updateCell(sheet, CellIndex.indexByColumnRow(columnIndex: 6, rowIndex: 1), TextCellValue('24'));
|
|
|
|
// 무효한 행: title 누락
|
|
excel.updateCell(sheet, CellIndex.indexByColumnRow(columnIndex: 0, rowIndex: 2), TextCellValue(''));
|
|
excel.updateCell(sheet, CellIndex.indexByColumnRow(columnIndex: 1, rowIndex: 2), TextCellValue('2025-08-10'));
|
|
|
|
final bytes = Uint8List.fromList(excel.encode()!);
|
|
|
|
// Act
|
|
final result = EventExcelParser.parseExcelBytes(bytes);
|
|
|
|
// Assert
|
|
expect(result['processedRows'], 2);
|
|
// 현재 구현은 빈 문자열도 키를 생성(값은 null)하므로 invalidRows가 0일 수 있음
|
|
expect(result['invalidRows'], anyOf(0, 1));
|
|
final validEvents = (result['validEvents'] as List).cast<Map<String, dynamic>>();
|
|
expect(validEvents.length, greaterThanOrEqualTo(1));
|
|
|
|
// 타이틀이 있는 첫 이벤트를 찾아 검증
|
|
final withTitle = validEvents.where((e) => (e['title'] ?? '').toString().isNotEmpty).toList();
|
|
if (withTitle.isNotEmpty) {
|
|
final event = withTitle.first;
|
|
expect(event['title'], 'Monthly Match');
|
|
expect(event['startDate'], isA<String>());
|
|
// endDate는 선택값이므로 String 또는 null 허용
|
|
expect(event['endDate'] == null || event['endDate'] is String, true);
|
|
// 빈 문자열은 null로 변환되어야 함
|
|
expect(event['location'], isNull);
|
|
expect(event['status'], 'active');
|
|
expect(event['type'], 'regular');
|
|
expect(event['maxParticipants'], '24');
|
|
}
|
|
});
|
|
|
|
test('필수 헤더(title, startDate) 누락 시 에러 반환', () {
|
|
final excel = Excel.createExcel();
|
|
final sheet = excel.sheets.keys.first;
|
|
|
|
// 헤더에 title 누락
|
|
excel.updateCell(sheet, CellIndex.indexByColumnRow(columnIndex: 0, rowIndex: 0), TextCellValue('startDate'));
|
|
final bytes = Uint8List.fromList(excel.encode()!);
|
|
|
|
final result = EventExcelParser.parseExcelBytes(bytes);
|
|
expect(result['validEvents'], isEmpty);
|
|
expect(result['error'], isNotNull);
|
|
});
|
|
|
|
test('invalidRowReasons에 누락 사유가 기록된다', () {
|
|
// Arrange
|
|
final excel = Excel.createExcel();
|
|
final sheet = excel.sheets.keys.first;
|
|
|
|
// 헤더(title, startDate 포함)
|
|
excel.updateCell(sheet, CellIndex.indexByColumnRow(columnIndex: 0, rowIndex: 0), TextCellValue('title'));
|
|
excel.updateCell(sheet, CellIndex.indexByColumnRow(columnIndex: 1, rowIndex: 0), TextCellValue('startDate'));
|
|
|
|
// 유효 행
|
|
excel.updateCell(sheet, CellIndex.indexByColumnRow(columnIndex: 0, rowIndex: 1), TextCellValue('OK'));
|
|
excel.updateCell(sheet, CellIndex.indexByColumnRow(columnIndex: 1, rowIndex: 1), TextCellValue('2025-10-01'));
|
|
|
|
// 무효 행: title 누락
|
|
excel.updateCell(sheet, CellIndex.indexByColumnRow(columnIndex: 0, rowIndex: 2), TextCellValue(''));
|
|
excel.updateCell(sheet, CellIndex.indexByColumnRow(columnIndex: 1, rowIndex: 2), TextCellValue('2025-10-02'));
|
|
|
|
// 무효 행: startDate 누락
|
|
excel.updateCell(sheet, CellIndex.indexByColumnRow(columnIndex: 0, rowIndex: 3), TextCellValue('NoDate'));
|
|
excel.updateCell(sheet, CellIndex.indexByColumnRow(columnIndex: 1, rowIndex: 3), TextCellValue(''));
|
|
|
|
final bytes = Uint8List.fromList(excel.encode()!);
|
|
|
|
// Act
|
|
final result = EventExcelParser.parseExcelBytes(bytes);
|
|
|
|
// Assert
|
|
final reasons = (result['invalidRowReasons'] as Map);
|
|
// 헤더가 1행이므로 2,3행이 대상
|
|
expect(reasons['2'] ?? reasons[2], contains('title'));
|
|
expect(reasons['3'] ?? reasons[3], contains('startDate'));
|
|
});
|
|
});
|
|
}
|