Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 8 additions & 21 deletions server/frontend/src/components/Bugs/PublicationForm.vue
Original file line number Diff line number Diff line change
Expand Up @@ -710,7 +710,7 @@ import * as api from "../../api";
import mime from "mime";
import * as bugzillaApi from "../../bugzilla_api";
import * as HandlebarsHelpers from "../../handlebars_helpers";
import { errorParser } from "../../helpers";
import { errorParser, parseFilename, buildFilename } from "../../helpers";
import CrashDataSection from "./CrashDataSection.vue";
import FullPPCSelect from "./FullPPCSelect.vue";
import HelpPopover from "./HelpPopover.vue";
Expand Down Expand Up @@ -821,30 +821,17 @@ export default defineComponent({
});

const filenameWithExtension = computed(() => {
return `${fileName.value}.${fileExtension.value}`;
return buildFilename(fileName.value, fileExtension.value);
});

watch([entry, template], () => {
if (entry.value) {
// Extract the original testcase path and get the extension
const originalTestcasePath = entry.value.testcase.split("/");
const originalFilename =
originalTestcasePath[originalTestcasePath.length - 1];
const originalParts = originalFilename.split(".");
const originalExtension = originalParts[originalParts.length - 1];

// If template has a testcase_filename, extract just the base name (without extension)
if (template.value?.testcase_filename) {
const templateParts = template.value.testcase_filename.split(".");
// If the template filename has an extension, remove it to get just the base name
fileName.value =
templateParts.slice(0, -1).join(".") || templateParts[0];
} else {
// Use the original filename without extension
fileName.value = originalParts.slice(0, -1).join(".");
}

fileExtension.value = originalExtension;
const { basename, extension } = parseFilename(
entry.value.testcase,
template.value?.testcase_filename,
);
fileName.value = basename;
fileExtension.value = extension;
}
});

Expand Down
42 changes: 42 additions & 0 deletions server/frontend/src/helpers.js
Original file line number Diff line number Diff line change
Expand Up @@ -220,3 +220,45 @@ export function formatMonthly(d) {
const date = new Date(d);
return `${months[date.getMonth()]} ${date.getFullYear()}`;
}

/**
* Parse a testcase file path into basename and extension
* @param {string} testcasePath - Full path to the testcase file (e.g. "/path/to/test.txt")
* @param {string|null} templateFilename - Optional template filename to use instead of original
* @returns {{basename: string, extension: string|null}} Object with basename and extension
*/
export function parseFilename(testcasePath, templateFilename = null) {
const pathParts = testcasePath.split("/");
const originalFilename = pathParts[pathParts.length - 1];
const originalParts = originalFilename.split(".");

const hasExtension = originalParts.length > 1;
const extension = hasExtension
? originalParts[originalParts.length - 1]
: null;

let basename;
if (templateFilename) {
const templateParts = templateFilename.split(".");
basename =
templateParts.length > 1
? templateParts.slice(0, -1).join(".")
: templateParts[0];
} else {
basename = hasExtension
? originalParts.slice(0, -1).join(".")
: originalParts[0];
}

return { basename, extension };
}

/**
* Build a filename from basename and extension
* @param {string} basename - The base filename without extension
* @param {string|null} extension - Optional file extension (without dot)
* @returns {string} Complete filename with extension if provided
*/
export function buildFilename(basename, extension) {
return extension ? `${basename}.${extension}` : basename;
}
58 changes: 58 additions & 0 deletions server/frontend/tests/helpers.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import { parseFilename, buildFilename } from "../src/helpers";

describe("parseFilename", () => {
test.each([
[
"testcase with file extension",
"tests/test.txt",
"testcase.zip",
{ basename: "testcase", extension: "txt" },
],
[
"testcase without an extension",
"tests/original",
"template_name.html",
{ basename: "template_name", extension: null },
],
[
"testcase with no basename",
"test/.bin",
null,
{ basename: "", extension: "bin" },
],
[
"testcase with an extension (no template)",
"tests/test.txt",
null,
{ basename: "test", extension: "txt" },
],
[
"testcase without an extension (no template)",
"tests/test",
null,
{ basename: "test", extension: null },
],
[
"testcase with multiple dots (no template)",
"test/test.min.js",
null,
{ basename: "test.min", extension: "js" },
],
])("%s", (_description, testcasePath, templateFilename, expected) => {
const result = parseFilename(testcasePath, templateFilename);
expect(result).toEqual(expected);
});
});

describe("buildFilename", () => {
test.each([
["testcase with an extension", "test", "txt", "test.txt"],
["testcase without an extension", "test", null, "test"],
["testcase with an empty extension", "test", "", "test"],
["testcase with multiple dots", "test.min", "js", "test.min.js"],
["testcase with an empty basename", "", "bin", ".bin"],
])("%s", (_description, basename, extension, expected) => {
const result = buildFilename(basename, extension);
expect(result).toBe(expected);
});
});