Skip to content

Commit 0929b19

Browse files
Copilotfgreinacher
andcommitted
refactor: move generic package label validator to top level and consolidate tests
Co-authored-by: fgreinacher <[email protected]>
1 parent b90cf02 commit 0929b19

File tree

2 files changed

+31
-133
lines changed

2 files changed

+31
-133
lines changed

lib/verify.js

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,22 @@ const isStringOrStringArray = (value) =>
1313
const isArrayOf = (validator) => (array) => isArray(array) && array.every((value) => validator(value));
1414
const canBeDisabled = (validator) => (value) => value === false || validator(value);
1515

16+
const isValidGenericPackageLabel = (label) => {
17+
// GitLab generic package filename restrictions
18+
// Can contain: A-Z, a-z, 0-9, . _ - + ~ @ /
19+
// Cannot start with: ~ or @
20+
// Cannot end with: ~ or @
21+
// Cannot contain spaces
22+
if (!label) return true; // label is optional
23+
if (typeof label !== "string") return false;
24+
if (/\s/.test(label)) return false; // no spaces
25+
if (/^[~@]/.test(label)) return false; // cannot start with ~ or @
26+
if (/[~@]$/.test(label)) return false; // cannot end with ~ or @
27+
// Check if it only contains allowed characters
28+
if (!/^[A-Za-z0-9._\-+~@/]+$/.test(label)) return false;
29+
return true;
30+
};
31+
1632
const VALIDATORS = {
1733
assets: isArrayOf(
1834
(asset) =>
@@ -47,22 +63,6 @@ export default async (pluginConfig, context) => {
4763

4864
// Validate generic package labels
4965
if (options.assets && Array.isArray(options.assets)) {
50-
const isValidGenericPackageLabel = (label) => {
51-
// GitLab generic package filename restrictions
52-
// Can contain: A-Z, a-z, 0-9, . _ - + ~ @ /
53-
// Cannot start with: ~ or @
54-
// Cannot end with: ~ or @
55-
// Cannot contain spaces
56-
if (!label) return true; // label is optional
57-
if (typeof label !== "string") return false;
58-
if (/\s/.test(label)) return false; // no spaces
59-
if (/^[~@]/.test(label)) return false; // cannot start with ~ or @
60-
if (/[~@]$/.test(label)) return false; // cannot end with ~ or @
61-
// Check if it only contains allowed characters
62-
if (!/^[A-Za-z0-9._\-+~@/]+$/.test(label)) return false;
63-
return true;
64-
};
65-
6666
options.assets.forEach((asset) => {
6767
if (isPlainObject(asset) && asset.target === "generic_package" && asset.label) {
6868
if (!isValidGenericPackageLabel(asset.label)) {

test/verify.test.js

Lines changed: 15 additions & 117 deletions
Original file line numberDiff line numberDiff line change
@@ -989,135 +989,33 @@ test.serial(
989989
}
990990
);
991991

992-
test.serial("Throw SemanticReleaseError if generic package asset label contains spaces", async (t) => {
992+
test.serial("Throw SemanticReleaseError if generic package asset labels are invalid", async (t) => {
993993
const owner = "test_user";
994994
const repo = "test_repo";
995995
const env = { GITLAB_TOKEN: "gitlab_token" };
996-
const assets = [{ path: "file.css", label: "Style package", target: "generic_package" }];
997-
const gitlab = authenticate(env)
998-
.get(`/projects/${owner}%2F${repo}`)
999-
.reply(200, { permissions: { project_access: { access_level: 40 } } });
1000-
1001-
const {
1002-
errors: [error],
1003-
} = await t.throwsAsync(
1004-
verify(
1005-
{ assets },
1006-
{ env, options: { repositoryUrl: `https://gitlab.com/${owner}/${repo}.git` }, logger: t.context.logger }
1007-
)
1008-
);
1009-
t.is(error.name, "SemanticReleaseError");
1010-
t.is(error.code, "EINVALIDGENERICPACKAGELABEL");
1011-
t.true(gitlab.isDone());
1012-
});
1013-
1014-
test.serial("Throw SemanticReleaseError if generic package asset label starts with ~", async (t) => {
1015-
const owner = "test_user";
1016-
const repo = "test_repo";
1017-
const env = { GITLAB_TOKEN: "gitlab_token" };
1018-
const assets = [{ path: "file.css", label: "~invalid", target: "generic_package" }];
1019-
const gitlab = authenticate(env)
1020-
.get(`/projects/${owner}%2F${repo}`)
1021-
.reply(200, { permissions: { project_access: { access_level: 40 } } });
1022-
1023-
const {
1024-
errors: [error],
1025-
} = await t.throwsAsync(
1026-
verify(
1027-
{ assets },
1028-
{ env, options: { repositoryUrl: `https://gitlab.com/${owner}/${repo}.git` }, logger: t.context.logger }
1029-
)
1030-
);
1031-
t.is(error.name, "SemanticReleaseError");
1032-
t.is(error.code, "EINVALIDGENERICPACKAGELABEL");
1033-
t.true(gitlab.isDone());
1034-
});
1035-
1036-
test.serial("Throw SemanticReleaseError if generic package asset label starts with @", async (t) => {
1037-
const owner = "test_user";
1038-
const repo = "test_repo";
1039-
const env = { GITLAB_TOKEN: "gitlab_token" };
1040-
const assets = [{ path: "file.css", label: "@invalid", target: "generic_package" }];
1041-
const gitlab = authenticate(env)
1042-
.get(`/projects/${owner}%2F${repo}`)
1043-
.reply(200, { permissions: { project_access: { access_level: 40 } } });
1044-
1045-
const {
1046-
errors: [error],
1047-
} = await t.throwsAsync(
1048-
verify(
1049-
{ assets },
1050-
{ env, options: { repositoryUrl: `https://gitlab.com/${owner}/${repo}.git` }, logger: t.context.logger }
1051-
)
1052-
);
1053-
t.is(error.name, "SemanticReleaseError");
1054-
t.is(error.code, "EINVALIDGENERICPACKAGELABEL");
1055-
t.true(gitlab.isDone());
1056-
});
1057-
1058-
test.serial("Throw SemanticReleaseError if generic package asset label ends with ~", async (t) => {
1059-
const owner = "test_user";
1060-
const repo = "test_repo";
1061-
const env = { GITLAB_TOKEN: "gitlab_token" };
1062-
const assets = [{ path: "file.css", label: "invalid~", target: "generic_package" }];
1063-
const gitlab = authenticate(env)
1064-
.get(`/projects/${owner}%2F${repo}`)
1065-
.reply(200, { permissions: { project_access: { access_level: 40 } } });
1066-
1067-
const {
1068-
errors: [error],
1069-
} = await t.throwsAsync(
1070-
verify(
1071-
{ assets },
1072-
{ env, options: { repositoryUrl: `https://gitlab.com/${owner}/${repo}.git` }, logger: t.context.logger }
1073-
)
1074-
);
1075-
t.is(error.name, "SemanticReleaseError");
1076-
t.is(error.code, "EINVALIDGENERICPACKAGELABEL");
1077-
t.true(gitlab.isDone());
1078-
});
1079-
1080-
test.serial("Throw SemanticReleaseError if generic package asset label ends with @", async (t) => {
1081-
const owner = "test_user";
1082-
const repo = "test_repo";
1083-
const env = { GITLAB_TOKEN: "gitlab_token" };
1084-
const assets = [{ path: "file.css", label: "invalid@", target: "generic_package" }];
1085-
const gitlab = authenticate(env)
1086-
.get(`/projects/${owner}%2F${repo}`)
1087-
.reply(200, { permissions: { project_access: { access_level: 40 } } });
1088-
1089-
const {
1090-
errors: [error],
1091-
} = await t.throwsAsync(
1092-
verify(
1093-
{ assets },
1094-
{ env, options: { repositoryUrl: `https://gitlab.com/${owner}/${repo}.git` }, logger: t.context.logger }
1095-
)
1096-
);
1097-
t.is(error.name, "SemanticReleaseError");
1098-
t.is(error.code, "EINVALIDGENERICPACKAGELABEL");
1099-
t.true(gitlab.isDone());
1100-
});
1101-
1102-
test.serial("Throw SemanticReleaseError if generic package asset label contains invalid characters", async (t) => {
1103-
const owner = "test_user";
1104-
const repo = "test_repo";
1105-
const env = { GITLAB_TOKEN: "gitlab_token" };
1106-
const assets = [{ path: "file.css", label: "invalid$char", target: "generic_package" }];
996+
const assets = [
997+
{ path: "file1.css", label: "Style package", target: "generic_package" }, // contains spaces
998+
{ path: "file2.css", label: "~invalid", target: "generic_package" }, // starts with ~
999+
{ path: "file3.css", label: "@invalid", target: "generic_package" }, // starts with @
1000+
{ path: "file4.css", label: "invalid~", target: "generic_package" }, // ends with ~
1001+
{ path: "file5.css", label: "invalid@", target: "generic_package" }, // ends with @
1002+
{ path: "file6.css", label: "invalid$char", target: "generic_package" }, // contains invalid character
1003+
];
11071004
const gitlab = authenticate(env)
11081005
.get(`/projects/${owner}%2F${repo}`)
11091006
.reply(200, { permissions: { project_access: { access_level: 40 } } });
11101007

1111-
const {
1112-
errors: [error],
1113-
} = await t.throwsAsync(
1008+
const { errors } = await t.throwsAsync(
11141009
verify(
11151010
{ assets },
11161011
{ env, options: { repositoryUrl: `https://gitlab.com/${owner}/${repo}.git` }, logger: t.context.logger }
11171012
)
11181013
);
1119-
t.is(error.name, "SemanticReleaseError");
1120-
t.is(error.code, "EINVALIDGENERICPACKAGELABEL");
1014+
t.is(errors.length, 6);
1015+
errors.forEach((error) => {
1016+
t.is(error.name, "SemanticReleaseError");
1017+
t.is(error.code, "EINVALIDGENERICPACKAGELABEL");
1018+
});
11211019
t.true(gitlab.isDone());
11221020
});
11231021

0 commit comments

Comments
 (0)