feat(report): accomplishment report PDF + shared PDF helpers
- lib/utils/pdf/pdf_letterhead.dart: PdfBrand with load(), letterhead(), theme(), and pageFooter() shared across CRMC PDF documents - lib/widgets/pdf_preview_dialog.dart: showPdfPreviewDialog() with pdfrx PdfViewer.data preview, Print (Printing.layoutPdf) and Download (Printing.sharePdf) buttons - lib/screens/programmer_tasks/report/accomplishment_report_pdf.dart: buildAccomplishmentReportPdf() — A4 MultiPage with letterhead, info box, accomplishment table, footnote, summary, signatures, page footer - test/accomplishment_report_pdf_test.dart: 2 passing tests Co-Authored-By: claude-flow <ruv@ruv.net>
This commit is contained in:
@@ -0,0 +1,87 @@
|
||||
import 'dart:convert';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:tasq/screens/programmer_tasks/report/accomplishment_report_data.dart';
|
||||
import 'package:tasq/screens/programmer_tasks/report/accomplishment_report_pdf.dart';
|
||||
import 'package:tasq/utils/programmer_day_rows.dart';
|
||||
|
||||
void main() {
|
||||
TestWidgetsFlutterBinding.ensureInitialized();
|
||||
|
||||
AccomplishmentReportData populated() => AccomplishmentReportData(
|
||||
programmerName: 'John Doe',
|
||||
positionLabel: 'Programmer',
|
||||
periodStart: DateTime.utc(2026, 9, 1),
|
||||
periodEndInclusive: DateTime.utc(2026, 9, 30),
|
||||
days: [
|
||||
ReportDay(
|
||||
day: DateTime.utc(2026, 9, 1),
|
||||
statusTag: null,
|
||||
rows: [
|
||||
DaySheetRow(
|
||||
taskId: 't1',
|
||||
title: 'Fix login bug',
|
||||
category: 'Backend',
|
||||
kind: 'assignee',
|
||||
projectName: 'AuthService',
|
||||
helpedName: null,
|
||||
seconds: 3600,
|
||||
notes: ['Resolved null pointer exception'],
|
||||
),
|
||||
],
|
||||
),
|
||||
ReportDay(
|
||||
day: DateTime.utc(2026, 9, 2),
|
||||
statusTag: 'Pending',
|
||||
rows: [
|
||||
DaySheetRow(
|
||||
taskId: 't2',
|
||||
title: 'Add unit tests',
|
||||
category: 'Testing',
|
||||
kind: 'helper',
|
||||
projectName: null,
|
||||
helpedName: 'Jane Smith',
|
||||
seconds: 1800,
|
||||
notes: [],
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
excludedPending: 1,
|
||||
excludedDisapproved: 0,
|
||||
daysReported: 2,
|
||||
totalSeconds: 5400,
|
||||
tasksCompleted: 1,
|
||||
helpSeconds: 1800,
|
||||
secondsByCategory: {'Backend': 3600, 'Testing': 1800},
|
||||
approverName: 'Jane Reviewer',
|
||||
);
|
||||
|
||||
AccomplishmentReportData emptyPeriod() => AccomplishmentReportData(
|
||||
programmerName: 'John Doe',
|
||||
positionLabel: 'Programmer',
|
||||
periodStart: DateTime.utc(2026, 9, 1),
|
||||
periodEndInclusive: DateTime.utc(2026, 9, 30),
|
||||
days: [],
|
||||
excludedPending: 0,
|
||||
excludedDisapproved: 0,
|
||||
daysReported: 0,
|
||||
totalSeconds: 0,
|
||||
tasksCompleted: 0,
|
||||
helpSeconds: 0,
|
||||
secondsByCategory: {},
|
||||
approverName: null,
|
||||
);
|
||||
|
||||
test('populated report builds non-empty PDF bytes starting with %PDF',
|
||||
() async {
|
||||
final bytes = await buildAccomplishmentReportPdf(populated());
|
||||
expect(bytes.isNotEmpty, isTrue);
|
||||
expect(utf8.decode(bytes.sublist(0, 4)), equals('%PDF'));
|
||||
});
|
||||
|
||||
test('empty period builds a valid PDF', () async {
|
||||
final bytes = await buildAccomplishmentReportPdf(emptyPeriod());
|
||||
expect(bytes.isNotEmpty, isTrue);
|
||||
expect(utf8.decode(bytes.sublist(0, 4)), equals('%PDF'));
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user