pib-service-api 0.17.1

pib-service edit API
Documentation
// SPDX-FileCopyrightText: Politik im Blick developers
// SPDX-FileCopyrightText: Wolfgang Silbermayr <wolfgang@silbermayr.at>
//
// SPDX-License-Identifier: AGPL-3.0-or-later OR EUPL-1.2

use std::sync::Arc;

use axum::{
    Extension, Json,
    extract::{Query, State},
};
use pib_service_api_auth::user::UserInfo;
use pib_service_api_types::{Pagination, body::get::ResponseBody};
use pib_service_facade::Service;

use crate::Result;

pub(crate) async fn handle<E: Into<pib_service_facade::Error> + Send + Sync>(
    State(service): State<Arc<dyn Service<E>>>,
    Extension(user): Extension<UserInfo>,
    Query(pagination): Query<Pagination>,
) -> Result<Json<ResponseBody>>
where
    crate::Error: From<E>,
{
    Ok(Json(
        service.handle_body_get(user, pagination.into()).await?,
    ))
}

#[cfg(test)]
mod tests {
    use std::sync::Arc;

    use crate::Error;

    use super::{ResponseBody, handle};
    use axum::{
        Extension,
        extract::{Query, State},
    };
    use mockall::predicate::eq;
    use pib_service_api_auth::user::{Issuer, OidcSub, UserInfo};
    use pib_service_api_types::{Pagination, body::Body};
    use pib_service_core_types::{BodyId, UserId};
    use pib_service_facade::MockService;
    use pretty_assertions::{assert_eq, assert_matches};

    #[tokio::test]
    async fn valid() {
        let mut service = MockService::<pib_service_facade::Error>::new();

        let user_info = UserInfo {
            id: UserId::from_u128(0x5555),
            issuer: Issuer(String::from("http://auth.example.com")),
            sub: OidcSub("max.mustermann".to_string()),
            display_name: Some("Max Mustermann".to_string()),
            is_superuser: false,
        };

        let response_body = ResponseBody(pib_service_core_types::DataPage {
            data: vec![Body {
                id: BodyId::from_u128(0x2211),
                created: "2026-04-07T05:06:07+01:00".parse().unwrap(),
                modified: "2026-04-08T05:06:07+01:00".parse().unwrap(),
                short_name: None,
                name: "Hintertupfing".parse().unwrap(),
                website: None,
                license: None,
                license_valid_since: None,
                oparl_since: None,
                ags: "12345".to_string(),
                rgs: None,
                contact_email: None,
                contact_name: None,
                classification: None,
                is_public: false,
            }],
            pagination: pib_service_core_types::DataPagePagination {
                total_elements: 11,
                elements_per_page: 12,
                current_page: 13,
                total_pages: 14,
            },
        });

        {
            let response_body = response_body.clone();
            service
                .expect_handle_body_get()
                .times(1)
                .with(
                    eq(user_info),
                    eq(pib_service_facade::paging::Pagination::from(
                        Pagination::DEFAULT,
                    )),
                )
                .return_once(move |_, _| Ok(response_body));
        }

        let response = handle(
            State(Arc::new(service)),
            Extension(UserInfo {
                id: UserId::from_u128(0x5555),
                issuer: Issuer("http://auth.example.com".to_string()),
                sub: OidcSub("max.mustermann".to_string()),
                display_name: Some("Max Mustermann".to_string()),
                is_superuser: false,
            }),
            Query(Pagination::default()),
        )
        .await
        .unwrap();
        assert_eq!(response.0, response_body);
    }

    #[tokio::test]
    async fn invalid() {
        let mut service = MockService::new();

        let user_info = UserInfo {
            id: UserId::from_u128(0x5555),
            issuer: Issuer(String::from("http://auth.example.com")),
            sub: OidcSub("max.mustermann".to_string()),
            display_name: Some("Max Mustermann".to_string()),
            is_superuser: false,
        };

        service
            .expect_handle_body_get()
            .times(1)
            .with(
                eq(user_info.clone()),
                eq(pib_service_facade::paging::Pagination::from(
                    Pagination::DEFAULT,
                )),
            )
            .return_once(|_, _| Err(pib_service_facade::Error::NotFound));

        assert_matches!(
            handle(
                State(Arc::new(service)),
                Extension(user_info.clone()),
                Query(Pagination::default()),
            )
            .await,
            Err(Error::Service {
                source: pib_service_facade::Error::NotFound
            })
        );
    }
}