完善客户端发布渠道并接入模板库灰度
Project CI / AI game creator shell Rust shard 2/4 (push) Successful in 7m36s
Project CI / AI game creator shell Rust shard 3/4 (push) Successful in 7m37s
Project CI / AI game creator shell Rust shard 4/4 (push) Successful in 7m42s
Project CI / AI game creator shell Rust shard 1/4 (push) Successful in 7m51s
Project CI / AI game creator shell Rust smoke (push) Successful in 1m55s
Project CI / AI game creator shell Rust crates (push) Successful in 4m15s
Project CI / Repository checks (push) Successful in 4m45s
Project CI / Frontend tests (push) Successful in 7m47s
Project CI / Native shell tests (push) Successful in 9m33s
Project CI / Backend tests (push) Successful in 10m9s
Project CI / AI game creator shell web tests (push) Successful in 4m38s
Project CI / AI game creator shell Rust shard 2/4 (push) Successful in 7m36s
Project CI / AI game creator shell Rust shard 3/4 (push) Successful in 7m37s
Project CI / AI game creator shell Rust shard 4/4 (push) Successful in 7m42s
Project CI / AI game creator shell Rust shard 1/4 (push) Successful in 7m51s
Project CI / AI game creator shell Rust smoke (push) Successful in 1m55s
Project CI / AI game creator shell Rust crates (push) Successful in 4m15s
Project CI / Repository checks (push) Successful in 4m45s
Project CI / Frontend tests (push) Successful in 7m47s
Project CI / Native shell tests (push) Successful in 9m33s
Project CI / Backend tests (push) Successful in 10m9s
Project CI / AI game creator shell web tests (push) Successful in 4m38s
区分发布渠道与系统,支持 dev、release 和自定义渠道 允许网站通过服务端配置选择客户端下载检测渠道 接入模板库灰度权限并阻断退出和切号后的异步操作 补齐发布、下载、灰度与会话竞态测试及当前规范
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
use axum::{
|
||||
Json, Router,
|
||||
extract::State,
|
||||
http::{HeaderValue, StatusCode, header::CACHE_CONTROL},
|
||||
response::{IntoResponse, Response},
|
||||
routing::get,
|
||||
@@ -18,8 +19,8 @@ pub fn router(_state: AppState) -> Router<AppState> {
|
||||
Router::new().route("/api/client-downloads", get(client_downloads))
|
||||
}
|
||||
|
||||
async fn client_downloads() -> Response {
|
||||
download_response(fetch_latest_client_downloads().await)
|
||||
async fn client_downloads(State(state): State<AppState>) -> Response {
|
||||
download_response(fetch_latest_client_downloads(&state.config.client_download_channel).await)
|
||||
}
|
||||
|
||||
fn download_response(result: Result<ClientDownloads, ClientDownloadError>) -> Response {
|
||||
@@ -69,6 +70,29 @@ mod tests {
|
||||
use platform_oss::client_downloads::ClientDownload as SourceDownload;
|
||||
use serde_json::{Value, json};
|
||||
|
||||
#[tokio::test]
|
||||
async fn client_downloads_uses_server_config_and_does_not_accept_query_overrides() {
|
||||
use axum::{body::Body, http::Request};
|
||||
use tower::ServiceExt;
|
||||
let state = AppState::new(crate::config::AppConfig {
|
||||
client_download_channel: "dev-win".to_string(),
|
||||
..Default::default()
|
||||
})
|
||||
.unwrap();
|
||||
let app = router(state.clone()).with_state(state);
|
||||
let response = app
|
||||
.oneshot(
|
||||
Request::builder()
|
||||
.uri("/api/client-downloads?channel=dev&url=https://example.com")
|
||||
.body(Body::empty())
|
||||
.unwrap(),
|
||||
)
|
||||
.await
|
||||
.unwrap();
|
||||
assert_eq!(response.status(), StatusCode::BAD_GATEWAY);
|
||||
assert_eq!(response.headers()[CACHE_CONTROL], "no-store");
|
||||
}
|
||||
|
||||
async fn read_success(result: ClientDownloads) -> Value {
|
||||
let response = download_response(Ok(result));
|
||||
assert_eq!(response.status(), StatusCode::OK);
|
||||
@@ -151,6 +175,7 @@ mod tests {
|
||||
#[tokio::test]
|
||||
async fn upstream_failures_share_a_safe_retryable_uncached_error() {
|
||||
for error in [
|
||||
ClientDownloadError::InvalidChannel,
|
||||
ClientDownloadError::Transport,
|
||||
ClientDownloadError::UpstreamStatus,
|
||||
ClientDownloadError::ManifestTooLarge,
|
||||
|
||||
Reference in New Issue
Block a user