|
|
|
@ -9,6 +9,7 @@ print('paths:', len(d['paths'])) |
|
|
|
assert len(d['paths']) == 129, f"Expected 129 paths, got {len(d['paths'])}" |
|
|
|
|
|
|
|
paths = d['paths'] |
|
|
|
|
|
|
|
required = [ |
|
|
|
'/review-weight-templates', |
|
|
|
'/profile/me/review-weights', |
|
|
|
@ -142,14 +143,42 @@ print(" V33 report/block endpoints present (9 operations / 8 paths)") |
|
|
|
# Skill cloud endpoints (3 paths / 3 GET operations) |
|
|
|
for skill_path in ('/skills/word-cloud', '/skills/match', '/skills/learning-path'): |
|
|
|
assert 'get' in paths[skill_path], f"Missing GET {skill_path}" |
|
|
|
assert paths['/skills/word-cloud']['get'].get('operationId') == 'getWordCloud' |
|
|
|
assert paths['/skills/match']['get'].get('operationId') == 'getMatch' |
|
|
|
assert paths['/skills/learning-path']['get'].get('operationId') == 'getLearningPath' |
|
|
|
skill_operation_ids = { |
|
|
|
'/skills/word-cloud': 'getWordCloud', |
|
|
|
'/skills/match': 'getSkillMatch', |
|
|
|
'/skills/learning-path': 'getLearningPath', |
|
|
|
} |
|
|
|
for skill_path, skill_operation_id in skill_operation_ids.items(): |
|
|
|
assert paths[skill_path]['get'].get('operationId') == skill_operation_id |
|
|
|
http_methods = {'get', 'post', 'put', 'patch', 'delete', 'options', 'head', 'trace'} |
|
|
|
matching_operations = [ |
|
|
|
(method, path) |
|
|
|
for path, path_item in paths.items() |
|
|
|
for method, operation in path_item.items() |
|
|
|
if method in http_methods |
|
|
|
and operation.get('operationId') == skill_operation_id |
|
|
|
] |
|
|
|
assert matching_operations == [('get', skill_path)], ( |
|
|
|
f'{skill_operation_id} must not conflict: expected GET {skill_path}, got {matching_operations}' |
|
|
|
) |
|
|
|
assert paths['/skills/word-cloud']['get']['responses']['200']['content']['application/json']['schema']['$ref'] == '#/components/schemas/ApiResponseSkillCloudResponse' |
|
|
|
assert paths['/skills/match']['get']['responses']['200']['content']['application/json']['schema']['$ref'] == '#/components/schemas/ApiResponseSkillMatchResponse' |
|
|
|
assert paths['/skills/learning-path']['get']['responses']['200']['content']['application/json']['schema']['$ref'] == '#/components/schemas/ApiResponseSkillLearningPathResponse' |
|
|
|
|
|
|
|
for skill_path in ('/skills/word-cloud', '/skills/match', '/skills/learning-path'): |
|
|
|
unauthorized = paths[skill_path]['get']['responses']['401'] |
|
|
|
assert unauthorized['description'] == '未登录或令牌无效,由全局 Security 入口返回裸 JSON' |
|
|
|
assert unauthorized['content']['application/json']['schema']['$ref'] == '#/components/schemas/UnauthorizedResponse' |
|
|
|
example = unauthorized['content']['application/json']['example'] |
|
|
|
assert example == {'code': 401, 'message': 'not authenticated', 'timestamp': ''} |
|
|
|
assert 'requestId' not in example |
|
|
|
|
|
|
|
schemas = d['components']['schemas'] |
|
|
|
unauthorized_schema = schemas.get('UnauthorizedResponse') |
|
|
|
assert unauthorized_schema is not None, 'Missing schema: UnauthorizedResponse' |
|
|
|
assert unauthorized_schema.get('additionalProperties') is False |
|
|
|
assert set(unauthorized_schema.get('required', [])) == {'code', 'message', 'timestamp'} |
|
|
|
assert set(unauthorized_schema.get('properties', {})) == {'code', 'message', 'timestamp'} |
|
|
|
skill_schema_fields = { |
|
|
|
'SkillCloudNode': {'id', 'code', 'name'}, |
|
|
|
'SkillCloudItem': {'rank', 'skillId', 'skillCode', 'nameZh', 'nameEn', 'sourceType', 'sourceCode', 'categoryId', 'categoryName', 'heat', 'heatSourceCode', 'heatElementId', 'heatProxy'}, |
|
|
|
|