Skip to content

Commit a9f052d

Browse files
authored
fix: make package name mandatory
an English package name should be mandatory as it's used as a fallback
1 parent fe8a2ac commit a9f052d

File tree

5 files changed

+28
-10
lines changed

5 files changed

+28
-10
lines changed

questionpy_common/manifest.py

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
from keyword import iskeyword, issoftkeyword
88
from typing import Annotated, NewType
99

10-
from pydantic import BaseModel, ByteSize, PositiveInt, conset, field_validator
10+
from pydantic import BaseModel, ByteSize, PositiveInt, StringConstraints, conset, field_validator
1111
from pydantic.fields import Field
1212

1313

@@ -97,7 +97,7 @@ class SourceManifest(BaseModel):
9797
version: Annotated[str, Field(pattern=RE_SEMVER)]
9898
api_version: Annotated[str, Field(pattern=RE_API)]
9999
author: str
100-
name: dict[Bcp47LanguageTag, str] = {}
100+
name: dict[Bcp47LanguageTag, Annotated[str, StringConstraints(min_length=1)]] = Field(min_length=1)
101101
entrypoint: str | None = None
102102
url: str | None = None
103103
languages: list[Bcp47LanguageTag] = Field(min_length=1)
@@ -119,6 +119,16 @@ class SourceManifest(BaseModel):
119119
def ensure_is_valid_name(cls, value: str) -> str:
120120
return ensure_is_valid_name(value)
121121

122+
@field_validator("languages", "name")
123+
@classmethod
124+
def ensure_contains_english_translation(
125+
cls, value: list[Bcp47LanguageTag] | dict[Bcp47LanguageTag, str]
126+
) -> list[Bcp47LanguageTag] | dict[Bcp47LanguageTag, str]:
127+
if Bcp47LanguageTag("en") not in value:
128+
msg = "must contain an english translation"
129+
raise ValueError(msg)
130+
return value
131+
122132
@property
123133
def identifier(self) -> str:
124134
return f"@{self.namespace}/{self.short_name}"

questionpy_server/worker/runtime/package_location.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ def __init__(self, module_name: str, function_name: str = "init", manifest: Mani
6868
version="0.1.0-debug",
6969
api_version="0.1",
7070
author="Debug Modulovitch",
71+
name={Bcp47LanguageTag("en"): "Debug Package"},
7172
languages=[Bcp47LanguageTag("en")],
7273
)
7374

tests/questionpy_common/test_manifest.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,12 @@
1515
"version": "0.1.0",
1616
"api_version": "0.1",
1717
"author": "John Doe",
18+
"name": {"en": "Minimal Package"},
1819
"languages": ["en"],
1920
}
2021
maximal_manifest = {
2122
**minimal_manifest,
22-
"name": {"en": "test_name"},
23+
"name": {"en": "Maximal Package"},
2324
"entrypoint": "test_entrypoint",
2425
"url": "https://example.com/package",
2526
"languages": ["de", "en", "en-AU"],
@@ -66,7 +67,7 @@ def test_ignore_additional_properties(data: dict[str, Any]) -> None:
6667
("data", "error_message"),
6768
[
6869
# no manifest
69-
({}, r"5 validation errors for \w"),
70+
({}, r"6 validation errors for \w"),
7071
# 'name' is not a dict
7172
({**minimal_manifest, "name": "test_name"}, r"1 validation error for \w"),
7273
# 'type' is not a valid PackageType

tests/questionpy_server/repository/test_repository.py

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,15 +20,19 @@
2020
REPO_URL = "https://example.com/repo/"
2121
REPO_PACKAGE_VERSIONS_0 = RepoPackageVersionsFactory.build(
2222
manifest={
23-
"short_name": "package_1",
24-
"namespace": "namespace_1",
23+
"short_name": "package_0",
24+
"namespace": "namespace_0",
25+
"name": {"en": "Package 0"},
26+
"languages": ["en"],
2527
},
2628
versions=[{"sha256": "2", "version": "3.0.0", "api_version": "3.0"}],
2729
)
2830
REPO_PACKAGE_VERSIONS_1 = RepoPackageVersionsFactory.build(
2931
manifest={
30-
"short_name": "package_0",
31-
"namespace": "namespace_0",
32+
"short_name": "package_1",
33+
"namespace": "namespace_1",
34+
"name": {"en": "Package 1"},
35+
"languages": ["en"],
3236
},
3337
versions=[
3438
{"sha256": "0", "version": "1.0.0", "api_version": "1.0"},
@@ -142,7 +146,7 @@ async def test_log_warning_when_package_index_is_too_big_for_cache(
142146
async def test_get_package() -> None:
143147
repository = Repository(REPO_URL, Mock())
144148

145-
manifest = ManifestFactory.build(short_name="package", namespace="namespace")
149+
manifest = ManifestFactory.build()
146150
package_path = "path/to/package.qpy"
147151
package = RepoPackage(manifest=manifest, sha256="hash", size=1, path=package_path)
148152

tests/test_data/factories.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
from polyfactory.factories.pydantic_factory import ModelFactory
1010
from semver import Version
1111

12-
from questionpy_common.manifest import PartialPackagePermissions
12+
from questionpy_common.manifest import Bcp47LanguageTag, PartialPackagePermissions
1313
from questionpy_server.repository.models import RepoMeta, RepoPackageVersions
1414
from questionpy_server.utils.manifest import ComparableManifest
1515

@@ -37,6 +37,8 @@ class ManifestFactory(CustomFactory):
3737

3838
short_name = Use(lambda: ModelFactory.__faker__.word().lower() + "_sn")
3939
namespace = Use(lambda: ModelFactory.__faker__.word().lower() + "_ns")
40+
name = {Bcp47LanguageTag("en"): "Factory Package"}
41+
languages = [Bcp47LanguageTag("en")]
4042
url = Use(ModelFactory.__faker__.url)
4143
icon = None
4244
permissions = PartialPackagePermissions()

0 commit comments

Comments
 (0)