feat: hopefully last M4 closing
This commit is contained in:
@@ -696,7 +696,7 @@ mod tests {
|
||||
http_ok(
|
||||
r#"{"data":[{"id":"gpt-4.1-mini","name":"GPT 4.1 mini","context_window":128000,"max_output_tokens":8192,"modalities":["text"]},{"id":"gpt-4.1","modalities":["text","vision"]}]}"#,
|
||||
)
|
||||
});
|
||||
}, 1);
|
||||
let models = refresh_model_catalog(&AiEndpointConfig {
|
||||
kind: AiEndpointKind::Airplane,
|
||||
url: server,
|
||||
@@ -722,7 +722,7 @@ mod tests {
|
||||
http_ok(
|
||||
r#"{"choices":[{"message":{"content":"{\"title\":\"Better title\",\"excerpt\":\"Short summary\",\"slug\":\"better-title\"}"}}]}"#,
|
||||
)
|
||||
});
|
||||
}, 1);
|
||||
|
||||
let db = setup();
|
||||
save_endpoint(
|
||||
@@ -774,11 +774,177 @@ mod tests {
|
||||
assert_eq!(parts[1]["image_url"]["url"], "data:image/jpeg;base64,abc123");
|
||||
}
|
||||
|
||||
fn spawn_test_server(handler: impl Fn(String) -> String + Send + 'static) -> String {
|
||||
#[test]
|
||||
fn run_one_shot_supports_taxonomy_analysis_via_airplane_endpoint() {
|
||||
let response = run_airplane_one_shot(
|
||||
OneShotRequest {
|
||||
operation: OneShotOperation::AnalyzeTaxonomy,
|
||||
content: json!({
|
||||
"title": "Rust preview parity",
|
||||
"excerpt": "Closing M4",
|
||||
"content": "Rendering routes and previews",
|
||||
"tags": ["rendering"],
|
||||
"categories": ["engineering"]
|
||||
}),
|
||||
},
|
||||
r#"{"choices":[{"message":{"content":"{\"tags\":[\"rust\",\"preview\"],\"categories\":[\"engineering\"]}"}}]}"#,
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
response,
|
||||
OneShotResponse::Taxonomy(TaxonomySuggestion {
|
||||
tags: vec!["rust".to_string(), "preview".to_string()],
|
||||
categories: vec!["engineering".to_string()],
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn run_one_shot_supports_post_analysis_via_airplane_endpoint() {
|
||||
let response = run_airplane_one_shot(
|
||||
OneShotRequest {
|
||||
operation: OneShotOperation::AnalyzePost,
|
||||
content: json!({"title":"Draft title","excerpt":"","content":"Body"}),
|
||||
},
|
||||
r#"{"choices":[{"message":{"content":"{\"title\":\"Better title\",\"excerpt\":\"Short summary\",\"slug\":\"better-title\"}"}}]}"#,
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
response,
|
||||
OneShotResponse::PostAnalysis(PostAnalysisResult {
|
||||
title: "Better title".to_string(),
|
||||
excerpt: "Short summary".to_string(),
|
||||
slug: "better-title".to_string(),
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn run_one_shot_supports_language_detection_via_airplane_endpoint() {
|
||||
let response = run_airplane_one_shot(
|
||||
OneShotRequest {
|
||||
operation: OneShotOperation::DetectLanguage,
|
||||
content: json!({"text": "Bonjour tout le monde"}),
|
||||
},
|
||||
r#"{"choices":[{"message":{"content":"{\"language_code\":\"fr\"}"}}]}"#,
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
response,
|
||||
OneShotResponse::LanguageDetection(LanguageDetectionResult {
|
||||
language_code: "fr".to_string(),
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn run_one_shot_supports_post_translation_via_airplane_endpoint() {
|
||||
let response = run_airplane_one_shot(
|
||||
OneShotRequest {
|
||||
operation: OneShotOperation::TranslatePost {
|
||||
target_language: "de".to_string(),
|
||||
},
|
||||
content: json!({
|
||||
"title": "Hello",
|
||||
"excerpt": "Short summary",
|
||||
"content": "Body"
|
||||
}),
|
||||
},
|
||||
r#"{"choices":[{"message":{"content":"{\"title\":\"Hallo\",\"excerpt\":\"Kurzfassung\",\"content\":\"Inhalt\"}"}}]}"#,
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
response,
|
||||
OneShotResponse::Translation(TranslationResult {
|
||||
title: "Hallo".to_string(),
|
||||
excerpt: "Kurzfassung".to_string(),
|
||||
content: "Inhalt".to_string(),
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn run_one_shot_supports_image_analysis_via_airplane_endpoint() {
|
||||
let response = run_airplane_one_shot(
|
||||
OneShotRequest {
|
||||
operation: OneShotOperation::AnalyzeImage,
|
||||
content: json!({
|
||||
"title": "Existing title",
|
||||
"alt": "",
|
||||
"caption": "",
|
||||
"filename": "hero.jpg",
|
||||
"mime_type": "image/jpeg",
|
||||
"image_data_url": "data:image/jpeg;base64,abc123"
|
||||
}),
|
||||
},
|
||||
r#"{"choices":[{"message":{"content":"{\"title\":\"Hero image\",\"alt\":\"A scenic mountain\",\"caption\":\"Sunrise over the ridge\"}"}}]}"#,
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
response,
|
||||
OneShotResponse::ImageAnalysis(ImageAnalysisResult {
|
||||
title: "Hero image".to_string(),
|
||||
alt: "A scenic mountain".to_string(),
|
||||
caption: "Sunrise over the ridge".to_string(),
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn run_one_shot_supports_media_translation_via_airplane_endpoint() {
|
||||
let response = run_airplane_one_shot(
|
||||
OneShotRequest {
|
||||
operation: OneShotOperation::TranslateMedia {
|
||||
target_language: "it".to_string(),
|
||||
},
|
||||
content: json!({
|
||||
"title": "Mountain",
|
||||
"alt": "Snowy ridge",
|
||||
"caption": "Morning light"
|
||||
}),
|
||||
},
|
||||
r#"{"choices":[{"message":{"content":"{\"title\":\"Montagna\",\"alt\":\"Cresta innevata\",\"caption\":\"Luce del mattino\"}"}}]}"#,
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
response,
|
||||
OneShotResponse::MediaTranslation(MediaTranslationResult {
|
||||
title: "Montagna".to_string(),
|
||||
alt: "Cresta innevata".to_string(),
|
||||
caption: "Luce del mattino".to_string(),
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
fn run_airplane_one_shot(request: OneShotRequest, body: &'static str) -> OneShotResponse {
|
||||
let server = spawn_test_server(
|
||||
move |incoming| {
|
||||
assert!(incoming.starts_with("POST /v1/chat/completions HTTP/1.1"));
|
||||
http_ok(body)
|
||||
},
|
||||
1,
|
||||
);
|
||||
|
||||
let db = setup();
|
||||
save_endpoint(
|
||||
db.conn(),
|
||||
&AiEndpointConfig {
|
||||
kind: AiEndpointKind::Airplane,
|
||||
url: server,
|
||||
model: "llama3.2".to_string(),
|
||||
api_key: None,
|
||||
},
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
run_one_shot(db.conn(), true, &request).unwrap()
|
||||
}
|
||||
|
||||
fn spawn_test_server(handler: impl Fn(String) -> String + Send + 'static, request_count: usize) -> String {
|
||||
let listener = TcpListener::bind("127.0.0.1:0").unwrap();
|
||||
let addr = listener.local_addr().unwrap();
|
||||
thread::spawn(move || {
|
||||
for stream in listener.incoming().take(2) {
|
||||
for stream in listener.incoming().take(request_count) {
|
||||
let mut stream = stream.unwrap();
|
||||
let mut buffer = [0_u8; 8192];
|
||||
let size = stream.read(&mut buffer).unwrap();
|
||||
|
||||
@@ -760,4 +760,139 @@ mod tests {
|
||||
assert!(!featured_response.html.contains("<h2 class=\"post-title\""));
|
||||
assert!(!featured_response.html.contains("Featured Post"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn preview_renders_tag_archive_pagination_and_date_routes() {
|
||||
let db = Database::open_in_memory().unwrap();
|
||||
let mut metadata = make_metadata();
|
||||
metadata.max_posts_per_page = 1;
|
||||
|
||||
let mut oldest = make_post();
|
||||
oldest.post.id = "post-1".into();
|
||||
oldest.post.slug = "alpha".into();
|
||||
oldest.post.title = "Alpha".into();
|
||||
oldest.post.tags = vec!["Rust".into()];
|
||||
oldest.post.published_at = Some(1_709_568_000_000);
|
||||
oldest.post.created_at = 1_709_568_000_000;
|
||||
oldest.body_markdown = "Alpha body".into();
|
||||
|
||||
let mut newest = make_post();
|
||||
newest.post.id = "post-2".into();
|
||||
newest.post.slug = "beta".into();
|
||||
newest.post.title = "Beta".into();
|
||||
newest.post.tags = vec!["Rust".into()];
|
||||
newest.post.published_at = Some(1_710_086_400_000);
|
||||
newest.post.created_at = 1_710_086_400_000;
|
||||
newest.body_markdown = "Beta body".into();
|
||||
|
||||
let mut april = make_post();
|
||||
april.post.id = "post-3".into();
|
||||
april.post.slug = "gamma".into();
|
||||
april.post.title = "Gamma".into();
|
||||
april.post.tags = vec!["Preview".into()];
|
||||
april.post.published_at = Some(1_712_016_000_000);
|
||||
april.post.created_at = 1_712_016_000_000;
|
||||
april.body_markdown = "Gamma body".into();
|
||||
|
||||
let posts = vec![
|
||||
(oldest.post.clone(), oldest.body_markdown.clone()),
|
||||
(newest.post.clone(), newest.body_markdown.clone()),
|
||||
(april.post.clone(), april.body_markdown.clone()),
|
||||
];
|
||||
|
||||
let tag_first = build_preview_response(
|
||||
db.conn(),
|
||||
Path::new("."),
|
||||
"project-1",
|
||||
&metadata,
|
||||
&posts,
|
||||
"/tag/rust",
|
||||
)
|
||||
.unwrap();
|
||||
assert_eq!(tag_first.status_code, 200);
|
||||
assert!(tag_first.html.contains("Beta body"));
|
||||
assert!(!tag_first.html.contains("Alpha body"));
|
||||
|
||||
let tag_second = build_preview_response(
|
||||
db.conn(),
|
||||
Path::new("."),
|
||||
"project-1",
|
||||
&metadata,
|
||||
&posts,
|
||||
"/tag/rust/page/2",
|
||||
)
|
||||
.unwrap();
|
||||
assert_eq!(tag_second.status_code, 200);
|
||||
assert!(tag_second.html.contains("Alpha body"));
|
||||
assert!(!tag_second.html.contains("Beta body"));
|
||||
|
||||
let year_archive = build_preview_response(
|
||||
db.conn(),
|
||||
Path::new("."),
|
||||
"project-1",
|
||||
&metadata,
|
||||
&posts,
|
||||
"/2024",
|
||||
)
|
||||
.unwrap();
|
||||
assert_eq!(year_archive.status_code, 200);
|
||||
assert!(year_archive.html.contains("Gamma body"));
|
||||
assert!(!year_archive.html.contains("Beta body"));
|
||||
|
||||
let year_archive_page_two = build_preview_response(
|
||||
db.conn(),
|
||||
Path::new("."),
|
||||
"project-1",
|
||||
&metadata,
|
||||
&posts,
|
||||
"/2024/page/2",
|
||||
)
|
||||
.unwrap();
|
||||
assert_eq!(year_archive_page_two.status_code, 200);
|
||||
assert!(year_archive_page_two.html.contains("Beta body"));
|
||||
|
||||
let month_archive = build_preview_response(
|
||||
db.conn(),
|
||||
Path::new("."),
|
||||
"project-1",
|
||||
&metadata,
|
||||
&posts,
|
||||
"/2024/03",
|
||||
)
|
||||
.unwrap();
|
||||
assert_eq!(month_archive.status_code, 200);
|
||||
assert!(month_archive.html.contains("Beta body"));
|
||||
assert!(!month_archive.html.contains("Alpha body"));
|
||||
assert!(!month_archive.html.contains("Gamma body"));
|
||||
|
||||
let month_archive_page_two = build_preview_response(
|
||||
db.conn(),
|
||||
Path::new("."),
|
||||
"project-1",
|
||||
&metadata,
|
||||
&posts,
|
||||
"/2024/03/page/2",
|
||||
)
|
||||
.unwrap();
|
||||
assert_eq!(month_archive_page_two.status_code, 200);
|
||||
assert!(month_archive_page_two.html.contains("Alpha body"));
|
||||
assert!(!month_archive_page_two.html.contains("Beta body"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn preview_returns_not_found_template_for_unknown_routes() {
|
||||
let db = Database::open_in_memory().unwrap();
|
||||
let response = build_preview_response(
|
||||
db.conn(),
|
||||
Path::new("."),
|
||||
"project-1",
|
||||
&make_metadata(),
|
||||
&[(make_post().post, make_post().body_markdown)],
|
||||
"/missing/route",
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
assert_eq!(response.status_code, 404);
|
||||
assert!(response.html.contains("No rendered page exists for /missing/route"));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user