feat(v1.4.0): CSV/Excel/JSON/NextUp exports + hybrid smart year standing
- Export modules (export-csv/json/xlsx) mirroring the PDF layout, plus a Next Up import CSV matching the raycast/nextup column contract. - Hybrid Year Level: View Grades history (exact per-semester standing), falling back to units math (prospectus total - lacking), then profile. Popup adds a year-mode setting (auto/custom/off). - On-page button row now offers PDF / CSV / Excel / JSON / Next Up. - Bump version to 1.4.0. - Tag-only build workflow with an optional AMO sign step for a signed .xpi; separate ci.yml keeps tests on pushes/PRs. - Tests: year-standing parser tests + export tests (CSV quoting, JSON schema, XLSX structure); CI validates XLSX via openpyxl.
This commit is contained in:
@@ -0,0 +1,64 @@
|
||||
'use strict';
|
||||
// CI-only validation: build a sample study-load XLSX/CSV/JSON and confirm they
|
||||
// open in real readers. The XLSX is re-parsed with python3 openpyxl (installed
|
||||
// in CI), which catches malformed XML / cell-reference issues that the Node
|
||||
// ZIP-structure tests cannot.
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const os = require('os');
|
||||
const { buildStudyLoadXlsx } = require('../export-xlsx.js');
|
||||
const { buildStudyLoadCsv, buildNextUpCsv } = require('../export-csv.js');
|
||||
const { buildStudyLoadJson } = require('../export-json.js');
|
||||
|
||||
const data = {
|
||||
year: '2024',
|
||||
period: '1ST Semester',
|
||||
totalUnits: '21.00',
|
||||
header: {
|
||||
program: 'BACHELOR OF SCIENCE IN INFORMATION TECHNOLOGY',
|
||||
fullName: 'ADRIAN ALFRED CHIONG BONPIN',
|
||||
studentId: '22103625',
|
||||
semester: '1ST Semester 2024',
|
||||
yearLevel: '3'
|
||||
},
|
||||
courses: [
|
||||
{ group: '1', courseCode: 'IT 3101N', description: 'PLATFORM TECHNOLOGIES',
|
||||
schedule: 'F 01:30 PM - 04:30 PM LB486', faculty: 'TAN', units: '3.0', status: 'REGULAR' },
|
||||
{ group: '1', courseCode: 'CIS 1101', description: 'PROGRAMMING, INTRO',
|
||||
schedule: 'T Th 03:00 PM - 04:30 PM LB468', faculty: '', units: '3.0', status: 'REGULAR' }
|
||||
]
|
||||
};
|
||||
|
||||
const dir = fs.mkdtempSync(path.join(os.tmpdir(), 'ismis-export-'));
|
||||
|
||||
fs.writeFileSync(path.join(dir, 'study-load.xlsx'), Buffer.from(buildStudyLoadXlsx(data)));
|
||||
fs.writeFileSync(path.join(dir, 'study-load.csv'), buildStudyLoadCsv(data), 'utf8');
|
||||
fs.writeFileSync(path.join(dir, 'study-load.json'), JSON.stringify(buildStudyLoadJson(data), null, 2), 'utf8');
|
||||
fs.writeFileSync(path.join(dir, 'study-load-nextup.csv'), buildNextUpCsv(data), 'utf8');
|
||||
|
||||
console.log('wrote sample exports to', dir);
|
||||
|
||||
// XLSX: require python3 + openpyxl, parse and assert key cells.
|
||||
const { execSync } = require('child_process');
|
||||
const pyFile = path.join(dir, 'check.py');
|
||||
const py = `
|
||||
import openpyxl
|
||||
wb = openpyxl.load_workbook('${path.join(dir, 'study-load.xlsx')}')
|
||||
ws = wb.active
|
||||
assert ws.title == 'Study Load', ws.title
|
||||
assert ws['B2'].value == 'BACHELOR OF SCIENCE IN INFORMATION TECHNOLOGY', ws['B2'].value
|
||||
assert ws['B3'].value == 'ADRIAN ALFRED CHIONG BONPIN'
|
||||
assert ws['B6'].value == '3'
|
||||
assert ws['A10'].value == '1' and ws['B10'].value == 'IT 3101N'
|
||||
assert ws['F10'].value == '3.0'
|
||||
print('openpyxl OK')
|
||||
`;
|
||||
fs.writeFileSync(pyFile, py);
|
||||
try {
|
||||
execSync('python3 ' + JSON.stringify(pyFile), { stdio: 'inherit' });
|
||||
} catch (e) {
|
||||
console.error('openpyxl validation failed');
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
console.log('ALL EXPORT VALIDATION PASSED');
|
||||
Reference in New Issue
Block a user