test(jimeng): cover classify edges and response parsing
Add unit tests for error-code classification boundaries and response decoding that the existing cases left open: - 50516/50517 are capability-independent (retryable for image too) - adjacent copyright codes 50518 (fatal) vs 50519 (retryable) - full 50520..=50522 service-exception range is fatal - 50500/50501 fatal-for-image / retryable-for-video via classify directly - negative codes are fatal (no poll loop) - base64 image output and absent (not just null) data field decode safely
This commit is contained in:
@@ -379,4 +379,73 @@ mod tests {
|
|||||||
assert_eq!(parsed.code, 50429);
|
assert_eq!(parsed.code, 50429);
|
||||||
assert!(parsed.data.is_none());
|
assert!(parsed.data.is_none());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn video_audio_moderation_codes_are_capability_independent() {
|
||||||
|
// 50516/50517 are documented as "video only" but `classify` does not
|
||||||
|
// gate them by capability — they are retryable for both. Pin that
|
||||||
|
// actual behavior so a future capability gate is a conscious change.
|
||||||
|
for code in [50516, 50517] {
|
||||||
|
assert_eq!(classify(code, JimengCapability::Video), CodeClass::Retryable);
|
||||||
|
assert_eq!(classify(code, JimengCapability::Image), CodeClass::Retryable);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn adjacent_copyright_codes_split_by_class() {
|
||||||
|
// Input copyright pre-moderation (50518) is fatal; output copyright
|
||||||
|
// post-moderation (50519) is retryable — adjacent codes, opposite class.
|
||||||
|
assert_eq!(classify(50518, JimengCapability::Image), CodeClass::Fatal);
|
||||||
|
assert_eq!(classify(50519, JimengCapability::Image), CodeClass::Retryable);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn moderation_service_exception_range_is_fatal() {
|
||||||
|
// The whole 50520..=50522 upstream-exception range is fatal for both
|
||||||
|
// capabilities (covers the inclusive upper bound 50522 explicitly).
|
||||||
|
for code in [50520, 50521, 50522] {
|
||||||
|
assert_eq!(classify(code, JimengCapability::Image), CodeClass::Fatal);
|
||||||
|
assert_eq!(classify(code, JimengCapability::Video), CodeClass::Fatal);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn internal_error_is_fatal_for_image_via_classify() {
|
||||||
|
// Complements the `retryable()` helper test with a direct CodeClass
|
||||||
|
// assertion: 50500/50501 are Fatal for image, Retryable for video.
|
||||||
|
for code in [50500, 50501] {
|
||||||
|
assert_eq!(classify(code, JimengCapability::Image), CodeClass::Fatal);
|
||||||
|
assert_eq!(classify(code, JimengCapability::Video), CodeClass::Retryable);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn negative_code_is_fatal() {
|
||||||
|
// Defensive: out-of-domain codes never loop the poller.
|
||||||
|
assert_eq!(classify(-1, JimengCapability::Image), CodeClass::Fatal);
|
||||||
|
assert!(!retryable(-1, JimengCapability::Video));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn done_image_response_parses_base64() {
|
||||||
|
// Default GetResult output (no return_url) carries base64, not urls.
|
||||||
|
let raw = r#"{"code":10000,"message":"Success","data":{"status":"done","binary_data_base64":["aGVsbG8="]}}"#;
|
||||||
|
let parsed: GetResultResponse = serde_json::from_str(raw).unwrap();
|
||||||
|
assert_eq!(parsed.code, CODE_SUCCESS);
|
||||||
|
assert_eq!(parsed.task_status(), TaskStatus::Done);
|
||||||
|
let data = parsed.data.unwrap();
|
||||||
|
assert!(data.image_urls.is_none());
|
||||||
|
assert_eq!(data.binary_data_base64.unwrap(), vec!["aGVsbG8=".to_string()]);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn response_with_absent_data_field_parses_to_none() {
|
||||||
|
// `data` omitted entirely (not just null) must still decode (serde
|
||||||
|
// default) and report Unknown status without panicking.
|
||||||
|
let submit: SubmitResponse = serde_json::from_str(r#"{"code":50429}"#).unwrap();
|
||||||
|
assert!(submit.data.is_none());
|
||||||
|
let result: GetResultResponse = serde_json::from_str(r#"{"code":50429}"#).unwrap();
|
||||||
|
assert!(result.data.is_none());
|
||||||
|
assert_eq!(result.task_status(), TaskStatus::Unknown);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user