Skip to content

Commit

Permalink
Merge pull request #343 from bcgov/DAP-1003-extra-metadata
Browse files Browse the repository at this point in the history
DAP-1003: Extra metadata
  • Loading branch information
BradyMitch authored Nov 26, 2024
2 parents 6684e5b + d8af705 commit 2dba665
Show file tree
Hide file tree
Showing 4 changed files with 145 additions and 17 deletions.
18 changes: 16 additions & 2 deletions backend/src/modules/filelist/schemas/metadata.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,17 @@ export const fileMetadataSchema = new Schema(
filepath: { type: String, required: true },
filename: { type: String, required: true },
size: { type: String, required: true },
checksum: { type: String, required: true },
birthtime: { type: String, required: true },
lastModified: { type: String, required: true },
lastAccessed: { type: String, required: true },
checksum: { type: String, required: true },
lastSaved: { type: String, required: false },
authors: { type: String, required: false },
owner: { type: String, required: false },
company: { type: String, required: false },
computer: { type: String, required: false },
contentType: { type: String, required: false },
programName: { type: String, required: false },
},
{ _id: false }, // Prevents Mongoose from automatically creating an _id for each folder
);
Expand All @@ -49,10 +56,17 @@ export const fileMetadataZodSchema = z.object({
filepath: z.string(),
filename: z.string(),
size: z.string(),
checksum: z.string(),
birthtime: z.string(),
lastModified: z.string(),
lastAccessed: z.string(),
checksum: z.string(),
lastSaved: z.union([z.string(), z.null()]).optional(),
authors: z.union([z.string(), z.null()]).optional(),
owner: z.union([z.string(), z.null()]).optional(),
company: z.union([z.string(), z.null()]).optional(),
computer: z.union([z.string(), z.null()]).optional(),
contentType: z.union([z.string(), z.null()]).optional(),
programName: z.union([z.string(), z.null()]).optional(),
});

export type FileMetadataZodType = z.infer<typeof fileMetadataZodSchema>;
29 changes: 25 additions & 4 deletions backend/src/modules/filelist/utils/excel/worksheets/metadata.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,21 +13,35 @@ export const setupMetadata = ({ worksheet, files }: Data) => {
{ width: 50 },
{ width: 30 },
{ width: 20 },
{ width: 50 },
{ width: 20 },
{ width: 20 },
{ width: 20 },
{ width: 20 },
{ width: 20 },
{ width: 20 },
{ width: 20 },
{ width: 20 },
{ width: 20 },
{ width: 20 },
{ width: 50 },
];

// Add column headers
const headers = [
"Path",
"Name",
"Size",
"Checksum",
"Created On",
"Last Modified",
"Last Accessed",
"Checksum",
"Last Saved",
"Authors",
"Owner",
"Company",
"Computer",
"Content-Type",
"Program Name",
];
const headerRow = worksheet.addRow(headers);

Expand All @@ -51,7 +65,7 @@ export const setupMetadata = ({ worksheet, files }: Data) => {
// Enable sorting for the table headers
worksheet.autoFilter = {
from: "A1",
to: "G1",
to: "N1",
};

// Populate rows with data
Expand All @@ -60,10 +74,17 @@ export const setupMetadata = ({ worksheet, files }: Data) => {
row.filepath,
row.filename,
row.size,
row.checksum,
formatDate(row.birthtime),
formatDate(row.lastModified),
formatDate(row.lastAccessed),
row.checksum,
row.lastSaved ? formatDate(row.lastSaved) : "",
row?.authors ?? "",
row?.owner ?? "",
row?.company ?? "",
row?.computer ?? "",
row?.contentType ?? "",
row?.programName ?? "",
]);
});
};
65 changes: 62 additions & 3 deletions backend/tests/modules/filelist/schemas/metadata.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ describe("Folder and File Metadata Schemas", () => {

const document = new FolderModel(invalidFolderMetadata);

// Use validateSync with `runValidators` explicitly to catch type errors
// Validate and catch errors
try {
document.validateSync({ pathsToSkip: [], runValidators: true });
// biome-ignore lint/suspicious/noExplicitAny: <explanation>
Expand Down Expand Up @@ -47,7 +47,7 @@ describe("Folder and File Metadata Schemas", () => {

const document = new FileModel(invalidFileMetadata);

// Use validateSync with `runValidators` explicitly to catch type errors
// Validate and catch errors
try {
document.validateSync({ pathsToSkip: [], runValidators: true });
// biome-ignore lint/suspicious/noExplicitAny: <explanation>
Expand Down Expand Up @@ -91,15 +91,74 @@ describe("Folder and File Metadata Schemas", () => {
filepath: "/path/to/file",
filename: "file.txt",
size: "1024",
checksum: "abcd1234",
birthtime: "2023-01-01T00:00:00Z",
lastModified: "2023-01-02T00:00:00Z",
lastAccessed: "2023-01-03T00:00:00Z",
checksum: "abcd1234",
lastSaved: "2023-01-04T00:00:00Z",
authors: "Author Name",
owner: "Owner Name",
company: "Company Name",
computer: "Computer Name",
contentType: "text/plain",
programName: "Text Editor",
},
};

const document = new FileModel(validFileMetadata);
expect(() => document.validateSync()).not.toThrow();
});

it("should handle optional and null fields in folder metadata", () => {
const testSchema = new Schema({
folder: folderMetadataSchema,
});
const FolderModel = mongoose.model("FolderOptionalTest", testSchema);

const folderMetadataWithNulls = {
folder: {
schedule: null,
classification: null,
file: null,
opr: null,
startDate: null,
endDate: null,
soDate: null,
fdDate: null,
},
};

const document = new FolderModel(folderMetadataWithNulls);
expect(() => document.validateSync()).not.toThrow();
});

it("should handle optional and null fields in file metadata", () => {
const testSchema = new Schema({
file: fileMetadataSchema,
});
const FileModel = mongoose.model("FileOptionalTest", testSchema);

const fileMetadataWithNulls = {
file: {
filepath: "/path/to/file",
filename: "file.txt",
size: "1024",
checksum: "abcd1234",
birthtime: "2023-01-01T00:00:00Z",
lastModified: "2023-01-02T00:00:00Z",
lastAccessed: "2023-01-03T00:00:00Z",
lastSaved: null,
authors: null,
owner: null,
company: null,
computer: null,
contentType: null,
programName: null,
},
};

const document = new FileModel(fileMetadataWithNulls);
expect(() => document.validateSync()).not.toThrow();
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -39,18 +39,27 @@ describe("setupMetadata", () => {
setupMetadata({ worksheet, files });

// Check column widths
expect(worksheet.columns?.map((col) => col?.width)).toEqual([50, 30, 20, 20, 20, 20, 50]);
expect(worksheet.columns?.map((col) => col?.width)).toEqual([
50, 30, 20, 50, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
]);

// Check header row
const headerRow = worksheet.getRow(1);
const headers = [
"Path",
"Name",
"Size",
"Checksum",
"Created On",
"Last Modified",
"Last Accessed",
"Checksum",
"Last Saved",
"Authors",
"Owner",
"Company",
"Computer",
"Content-Type",
"Program Name",
];
headers.forEach((header, index) => {
const cell = headerRow.getCell(index + 1);
Expand All @@ -73,7 +82,7 @@ describe("setupMetadata", () => {
// Check autoFilter
expect(worksheet.autoFilter).toEqual({
from: "A1",
to: "G1",
to: "N1",
});

// Check data rows
Expand All @@ -85,10 +94,17 @@ describe("setupMetadata", () => {
expect(row.getCell(1).value).toBe(fileData.filepath);
expect(row.getCell(2).value).toBe(fileData.filename);
expect(row.getCell(3).value).toBe(fileData.size);
expect(row.getCell(4).value).toBe(formatDate(fileData.birthtime));
expect(row.getCell(5).value).toBe(formatDate(fileData.lastModified));
expect(row.getCell(6).value).toBe(formatDate(fileData.lastAccessed));
expect(row.getCell(7).value).toBe(fileData.checksum);
expect(row.getCell(4).value).toBe(fileData.checksum);
expect(row.getCell(5).value).toBe(formatDate(fileData.birthtime));
expect(row.getCell(6).value).toBe(formatDate(fileData.lastModified));
expect(row.getCell(7).value).toBe(formatDate(fileData.lastAccessed));
expect(row.getCell(8).value).toBe("");
expect(row.getCell(9).value).toBe("");
expect(row.getCell(10).value).toBe("");
expect(row.getCell(11).value).toBe("");
expect(row.getCell(12).value).toBe("");
expect(row.getCell(13).value).toBe("");
expect(row.getCell(14).value).toBe("");
});
});

Expand All @@ -103,6 +119,24 @@ describe("setupMetadata", () => {
const rows = worksheet.getRows(1, worksheet.rowCount) ?? [];
expect(rows.length).toBe(1); // Only header row
const headerRow = rows[0];
expect(headerRow.getCell(1).value).toBe("Path");
const headers = [
"Path",
"Name",
"Size",
"Checksum",
"Created On",
"Last Modified",
"Last Accessed",
"Last Saved",
"Authors",
"Owner",
"Company",
"Computer",
"Content-Type",
"Program Name",
];
headers.forEach((header, index) => {
expect(headerRow.getCell(index + 1).value).toBe(header);
});
});
});

0 comments on commit 2dba665

Please sign in to comment.