Login
4 branches 0 tags
Ben (T14/NixOS) Improved flake 41eb128 11 days ago 252 Commits
rubhub / tests / events_tests.rs
mod common;

use common::{Api, with_backend};
use reqwest::header::CONTENT_TYPE;

#[tokio::test(flavor = "current_thread")]
async fn test_global_events_endpoint_returns_sse_content_type() {
    with_backend(|state| async move {
        let api = Api::new(&state.config.base_url);

        // Create a user and project first
        api.register("testuser", "test@example.com", "password123456789")
            .await
            .unwrap();

        api.create_project("Test Project", "A test project")
            .await
            .unwrap();

        // Make request to global events endpoint
        let response = api.get_raw("/.events").await.unwrap();

        assert_eq!(response.status(), 200);
        assert_eq!(
            response.headers().get(CONTENT_TYPE).unwrap(),
            "text/event-stream"
        );
    })
    .await;
}

#[tokio::test(flavor = "current_thread")]
async fn test_user_events_endpoint_returns_sse_content_type() {
    with_backend(|state| async move {
        let api = Api::new(&state.config.base_url);

        api.register("testuser", "test@example.com", "password123456789")
            .await
            .unwrap();

        api.create_project("Test Project", "A test project")
            .await
            .unwrap();

        let response = api.get_raw("/~testuser/.events").await.unwrap();

        assert_eq!(response.status(), 200);
        assert_eq!(
            response.headers().get(CONTENT_TYPE).unwrap(),
            "text/event-stream"
        );
    })
    .await;
}

#[tokio::test(flavor = "current_thread")]
async fn test_project_events_endpoint_returns_sse_content_type() {
    with_backend(|state| async move {
        let api = Api::new(&state.config.base_url);

        api.register("testuser", "test@example.com", "password123456789")
            .await
            .unwrap();

        api.create_project("Test Project", "A test project")
            .await
            .unwrap();

        let response = api
            .get_raw("/~testuser/test-project/.events")
            .await
            .unwrap();

        assert_eq!(response.status(), 200);
        assert_eq!(
            response.headers().get(CONTENT_TYPE).unwrap(),
            "text/event-stream"
        );
    })
    .await;
}

#[tokio::test(flavor = "current_thread")]
async fn test_project_events_access_control() {
    with_backend(|state| async move {
        let api = Api::new(&state.config.base_url);

        // Create user and private project
        api.register("alice", "alice@example.com", "alicepassword123")
            .await
            .unwrap();

        api.create_project_with_access("Private Project", "A private project", "none")
            .await
            .unwrap();

        // Logout
        api.logout().await.unwrap();

        // Try to access private project events (should fail)
        let response = api
            .get_raw("/~alice/private-project/.events")
            .await
            .unwrap();

        assert_eq!(response.status(), 403);
    })
    .await;
}

#[tokio::test(flavor = "current_thread")]
async fn test_event_emission() {
    use rubhub::{RepoEvent, RepoEventInfo};
    use time::OffsetDateTime;

    with_backend(|state| async move {
        let api = Api::new(&state.config.base_url);

        api.register("testuser", "test@example.com", "password123456789")
            .await
            .unwrap();

        api.create_project("Test Project", "A test project")
            .await
            .unwrap();

        // Emit a test event
        state.emit_event(RepoEvent::BranchUpdated {
            info: RepoEventInfo {
                owner: "testuser".to_string(),
                project: "test-project".to_string(),
                commit_hash: "abc123".to_string(),
                timestamp: OffsetDateTime::now_utc(),
            },
            branch: "main".to_string(),
        });

        // Verify the endpoint is accessible
        // (Testing actual event reception would require async streaming which is complex)
        let response = api.get_raw("/.events").await.unwrap();
        assert_eq!(response.status(), 200);
    })
    .await;
}

#[tokio::test(flavor = "current_thread")]
async fn test_create_event_emission() {
    use rubhub::{AccessType, RepoEvent};
    use time::OffsetDateTime;

    with_backend(|state| async move {
        let api = Api::new(&state.config.base_url);

        api.register("testuser", "test@example.com", "password123456789")
            .await
            .unwrap();

        // Emit a create event
        state.emit_event(RepoEvent::RepositoryCreated {
            owner: "testuser".to_string(),
            project: "test-project".to_string(),
            public_access: AccessType::Read,
            timestamp: OffsetDateTime::now_utc(),
        });

        // Verify event was emitted (basic test - channel accepts the event)
        // Full streaming verification would require async stream consumption
    })
    .await;
}

#[tokio::test(flavor = "current_thread")]
async fn test_delete_event_emission() {
    use rubhub::{AccessType, RepoEvent};
    use time::OffsetDateTime;

    with_backend(|state| async move {
        let api = Api::new(&state.config.base_url);

        api.register("testuser", "test@example.com", "password123456789")
            .await
            .unwrap();

        api.create_project("Test Project", "A test project")
            .await
            .unwrap();

        // Emit a delete event
        state.emit_event(RepoEvent::RepositoryDeleted {
            owner: "testuser".to_string(),
            project: "test-project".to_string(),
            public_access: AccessType::Read,
            timestamp: OffsetDateTime::now_utc(),
        });

        // Verify event was emitted (basic test - channel accepts the event)
        // Full streaming verification would require async stream consumption
    })
    .await;
}

#[tokio::test(flavor = "current_thread")]
async fn test_project_events_404_after_deletion() {
    with_backend(|state| async move {
        let api = Api::new(&state.config.base_url);

        api.register("testuser", "test@example.com", "password123456789")
            .await
            .unwrap();

        api.create_project("Test Project", "A test project")
            .await
            .unwrap();

        // Delete the project
        api.delete_project("testuser", "test-project")
            .await
            .unwrap();

        // Trying to access events for deleted project should 404
        let response = api
            .get_raw("/~testuser/test-project/.events")
            .await
            .unwrap();

        assert_eq!(response.status(), 404);
    })
    .await;
}