点赞和改造开关加入后台配置
This commit is contained in:
@@ -17,7 +17,9 @@ use tracing::{Level, Span, error, info_span};
|
||||
use crate::{
|
||||
auth::AuthenticatedAccessToken,
|
||||
backpressure::limit_concurrent_requests,
|
||||
creation_entry_config::require_creation_entry_route_enabled,
|
||||
creation_entry_config::{
|
||||
require_creation_entry_route_enabled, require_public_work_interaction_enabled,
|
||||
},
|
||||
error_middleware::normalize_error_response,
|
||||
http_error::AppError,
|
||||
modules,
|
||||
@@ -57,6 +59,10 @@ pub fn build_router(state: AppState) -> Router {
|
||||
state.clone(),
|
||||
require_creation_entry_route_enabled,
|
||||
))
|
||||
.layer(middleware::from_fn_with_state(
|
||||
state.clone(),
|
||||
require_public_work_interaction_enabled,
|
||||
))
|
||||
// HTTP 背压在业务路由外侧快拒绝,避免过载请求继续占用 SpacetimeDB facade 与业务执行资源。
|
||||
.layer(middleware::from_fn_with_state(
|
||||
BackpressureState::from_ref(&state),
|
||||
@@ -590,6 +596,37 @@ mod tests {
|
||||
);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn disabled_public_work_like_returns_service_unavailable() {
|
||||
let state = AppState::new(AppConfig::default()).expect("state should build");
|
||||
state.set_test_public_work_interaction_enabled(
|
||||
"puzzle",
|
||||
crate::creation_entry_config::PublicWorkInteractionAction::Like,
|
||||
false,
|
||||
);
|
||||
let app = build_router(state);
|
||||
|
||||
let response = app
|
||||
.oneshot(
|
||||
Request::builder()
|
||||
.method("POST")
|
||||
.uri("/api/runtime/puzzle/gallery/profile-1/like")
|
||||
.body(Body::empty())
|
||||
.expect("request should build"),
|
||||
)
|
||||
.await
|
||||
.expect("request should succeed");
|
||||
|
||||
assert_eq!(response.status(), StatusCode::SERVICE_UNAVAILABLE);
|
||||
let body = read_json_response(response).await;
|
||||
assert_eq!(
|
||||
body["error"]["details"]["reason"],
|
||||
"public_work_interaction_disabled"
|
||||
);
|
||||
assert_eq!(body["error"]["details"]["sourceType"], "puzzle");
|
||||
assert_eq!(body["error"]["details"]["action"], "like");
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn disabled_visual_novel_creation_route_returns_service_unavailable() {
|
||||
let app = build_router(AppState::new(AppConfig::default()).expect("state should build"));
|
||||
@@ -4228,6 +4265,62 @@ mod tests {
|
||||
assert_eq!(response.status(), StatusCode::BAD_REQUEST);
|
||||
}
|
||||
|
||||
/// 中文注释:验证后台作品互动配置保存后回到同一份入口配置响应。
|
||||
#[tokio::test]
|
||||
async fn admin_public_work_interactions_route_saves_form_payload() {
|
||||
let mut config = AppConfig::default();
|
||||
config.admin_username = Some("root".to_string());
|
||||
config.admin_password = Some("secret123".to_string());
|
||||
let app = build_router(AppState::new(config).expect("state should build"));
|
||||
let admin_token = read_admin_access_token(app.clone()).await;
|
||||
|
||||
let response = app
|
||||
.oneshot(
|
||||
Request::builder()
|
||||
.method("POST")
|
||||
.uri("/admin/api/creation-entry/config/interactions")
|
||||
.header("authorization", format!("Bearer {admin_token}"))
|
||||
.header("content-type", "application/json")
|
||||
.body(Body::from(
|
||||
serde_json::json!({
|
||||
"publicWorkInteractions": [
|
||||
{
|
||||
"sourceType": "puzzle",
|
||||
"likeEnabled": false,
|
||||
"remixEnabled": true,
|
||||
"likeDisabledMessage": "拼图点赞维护中。",
|
||||
"remixDisabledMessage": "拼图作品改造暂不可用。"
|
||||
}
|
||||
]
|
||||
})
|
||||
.to_string(),
|
||||
))
|
||||
.expect("interactions request should build"),
|
||||
)
|
||||
.await
|
||||
.expect("interactions request should succeed");
|
||||
|
||||
assert_eq!(response.status(), StatusCode::OK);
|
||||
let body = response
|
||||
.into_body()
|
||||
.collect()
|
||||
.await
|
||||
.expect("interactions body should collect")
|
||||
.to_bytes();
|
||||
let payload: Value =
|
||||
serde_json::from_slice(&body).expect("interactions payload should be json");
|
||||
let puzzle = payload["publicWorkInteractions"]
|
||||
.as_array()
|
||||
.expect("interactions should be array")
|
||||
.iter()
|
||||
.find(|item| item["sourceType"] == "puzzle")
|
||||
.expect("puzzle interaction should exist");
|
||||
|
||||
assert_eq!(puzzle["likeEnabled"], false);
|
||||
assert_eq!(puzzle["remixEnabled"], true);
|
||||
assert_eq!(puzzle["likeDisabledMessage"], "拼图点赞维护中。");
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn admin_debug_http_can_probe_healthz_when_authenticated() {
|
||||
let mut config = AppConfig::default();
|
||||
|
||||
Reference in New Issue
Block a user