• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

geo-engine / BioIS / 21947668680

12 Feb 2026 01:01PM UTC coverage: 80.094%. First build
21947668680

Pull #4

github

web-flow
Merge 388c0f176 into 66590e38d
Pull Request #4: feat: add NDVI process endpoint and OpenAPI documentation

11 of 12 branches covered (91.67%)

Branch coverage included in aggregate %.

1188 of 1485 new or added lines in 16 files covered. (80.0%)

1188 of 1485 relevant lines covered (80.0%)

1.61 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

75.81
/backend/src/handler.rs
1
use crate::auth::{AuthCodeResponse, UserSession};
2
use anyhow::Context;
3
use axum::{
4
    Json,
5
    extract::{Query, State},
6
    http::StatusCode,
7
    routing::MethodRouter,
8
};
9
use geoengine_openapi_client::apis::{configuration::Configuration, session_api::oidc_login};
10
use ogcapi::{services as ogcapi_services, types::common::Exception};
11
use utoipa::openapi::{Paths, RefOr, Schema};
12
use utoipa_axum::routes;
13

14
type Routes = (
15
    Vec<(String, RefOr<Schema>)>,
16
    Paths,
17
    MethodRouter<Configuration>,
18
);
19

NEW
20
pub fn routes() -> Routes {
×
NEW
21
    routes!(health_handler, auth_handler)
×
NEW
22
}
×
23

24
#[utoipa::path(get, path = "/health", responses((status = NO_CONTENT)))]
25
pub async fn health_handler() -> StatusCode {
1✔
26
    StatusCode::NO_CONTENT
1✔
27
}
1✔
28

NEW
29
#[utoipa::path(post, path = "/auth", tag = "User",
×
NEW
30
    responses(
×
NEW
31
        (
×
NEW
32
            status = OK,
×
NEW
33
            description = "The OIDC login flow was successful, and a user session has been created.",
×
NEW
34
            body = UserSession
×
NEW
35
        ),
×
NEW
36
        (
×
NEW
37
            status = INTERNAL_SERVER_ERROR,
×
NEW
38
            description = "A server error occurred.", 
×
NEW
39
            body = Exception,
×
NEW
40
            example = json!(Exception::new_from_status(500))
×
41
        )
42
    )
43
)]
44
pub async fn auth_handler(
1✔
45
    State(api_config): State<Configuration>,
1✔
46
    Query(redirect_uri): Query<String>,
1✔
47
    Json(auth_code_response): Json<AuthCodeResponse>,
1✔
48
) -> ogcapi_services::Result<Json<UserSession>> {
1✔
49
    let user_session = oidc_login(&api_config, &redirect_uri, auth_code_response.into())
1✔
50
        .await
1✔
51
        .context("Failed to perform OIDC login")?;
1✔
52

53
    Ok(Json(user_session.into()))
1✔
54
}
1✔
55

56
#[cfg(test)]
57
mod tests {
58
    use super::*;
59
    use crate::auth::AuthCodeResponse;
60
    use crate::config::GeoEngineInstance;
61
    use axum::extract::{Query, State};
62
    use axum::routing::get;
63
    use axum::{Json, Router};
64
    use axum::{body::Body, http::Request};
65
    use httptest::matchers::request::method;
66
    use httptest::{Expectation, Server, responders::json_encoded};
67
    use reqwest::StatusCode;
68
    use serde_json::json;
69
    use tower::ServiceExt;
70
    use url::Url;
71

72
    #[tokio::test]
73
    async fn test_health_route() {
1✔
74
        let app = Router::new().route("/health", get(health_handler));
1✔
75
        let request = Request::builder()
1✔
76
            .uri("/health")
1✔
77
            .body(Body::empty())
1✔
78
            .unwrap();
1✔
79

80
        let response = app.oneshot(request).await.unwrap();
1✔
81
        assert_eq!(response.status(), StatusCode::NO_CONTENT);
1✔
82
    }
1✔
83

84
    #[tokio::test]
85
    async fn test_auth_handler_with_mock_server() {
1✔
86
        // start mock server
87
        let server = Server::run();
1✔
88

89
        // respond to oidcLogin under an `/api` base with a valid user session
90
        server.expect(
1✔
91
            Expectation::matching(method("POST"))
1✔
92
                .respond_with(json_encoded(json!({
1✔
93
                    "id": "d1322969-5ada-4a2c-bacf-a3045383ba41",
1✔
94
                    "user": { "id": "9273bb02-95a6-49fe-b1c6-a32ff171d4a3", "email": "foo@example.com", "realName": "Max Muster" },
1✔
95
                    "created": "2020-01-01T00:00:00Z",
1✔
96
                    "validUntil": "2021-01-01T00:00:00Z",
1✔
97
                    "project": null,
1✔
98
                    "view": null,
1✔
99
                    "roles": []
1✔
100
                })))
101
        );
102

103
        let api_config = GeoEngineInstance {
1✔
104
            base_url: Url::parse(&server.url_str("")).expect("valid url"),
1✔
105
        }
1✔
106
        .api_config(None);
1✔
107

108
        // build test inputs
109
        let redirect = "http://example.com/redirect".to_string();
1✔
110
        let auth_code_response = AuthCodeResponse {
1✔
111
            code: String::new(),
1✔
112
            session_state: String::new(),
1✔
113
            state: String::new(),
1✔
114
        };
1✔
115

116
        // call handler
117
        let res = auth_handler(State(api_config), Query(redirect), Json(auth_code_response)).await;
1✔
118

119
        assert!(res.is_ok(), "expected Ok(UserSession) from auth_handler");
1✔
120
    }
1✔
121
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc