diff --git a/radicle-httpd/src/api/v1/delegates.rs b/radicle-httpd/src/api/v1/delegates.rs index 9af0950ce..9d9aa9523 100644 --- a/radicle-httpd/src/api/v1/delegates.rs +++ b/radicle-httpd/src/api/v1/delegates.rs @@ -167,7 +167,7 @@ mod routes { "closed": 0, }, "id": RID, - "seeding": 0, + "seeding": 1, }, { "name": "again-hello-world", @@ -195,7 +195,7 @@ mod routes { "closed": 0, }, "id": "rad:z4GypKmh1gkEfmkXtarcYnkvtFUfE", - "seeding": 0, + "seeding": 1, } ]) ); @@ -245,7 +245,7 @@ mod routes { "closed": 0, }, "id": RID, - "seeding": 0, + "seeding": 1, }, { "name": "again-hello-world", @@ -273,7 +273,7 @@ mod routes { "closed": 0, }, "id": "rad:z4GypKmh1gkEfmkXtarcYnkvtFUfE", - "seeding": 0, + "seeding": 1, } ]) ); diff --git a/radicle-httpd/src/api/v1/node.rs b/radicle-httpd/src/api/v1/node.rs index b1f7c8c39..e1a7a0d73 100644 --- a/radicle-httpd/src/api/v1/node.rs +++ b/radicle-httpd/src/api/v1/node.rs @@ -112,7 +112,7 @@ mod routes { use axum::extract::connect_info::MockConnectInfo; use axum::http::StatusCode; use pretty_assertions::assert_eq; - use serde_json::json; + use serde_json::{json, Value}; use crate::test::*; @@ -206,6 +206,21 @@ mod routes { let response = get(&app, format!("/nodes/{nid}/inventory")).await; assert_eq!(response.status(), StatusCode::OK); - assert_eq!(response.json().await, json!([])); + let json_response = response.json().await; + + let mut arr = match json_response { + Value::Array(arr) => arr, + _ => panic!("Expected JSON array in response"), + }; + + arr.sort_by(|a, b| a.as_str().cmp(&b.as_str())); + + assert_eq!( + arr, + vec![ + json!("rad:z4FucBZHZMCsxTyQE1dfE2YR59Qbp"), + json!("rad:z4GypKmh1gkEfmkXtarcYnkvtFUfE"), + ] + ); } } diff --git a/radicle-httpd/src/api/v1/projects.rs b/radicle-httpd/src/api/v1/projects.rs index 7f372c6a2..fae441762 100644 --- a/radicle-httpd/src/api/v1/projects.rs +++ b/radicle-httpd/src/api/v1/projects.rs @@ -760,7 +760,7 @@ mod routes { "closed": 0, }, "id": RID, - "seeding": 0, + "seeding": 1, }, { "name": "again-hello-world", @@ -788,7 +788,7 @@ mod routes { "closed": 0, }, "id": "rad:z4GypKmh1gkEfmkXtarcYnkvtFUfE", - "seeding": 0, + "seeding": 1, }, ]) ); @@ -829,7 +829,7 @@ mod routes { "closed": 0, }, "id": RID, - "seeding": 0, + "seeding": 1, }, { "name": "again-hello-world", @@ -857,7 +857,7 @@ mod routes { "closed": 0, }, "id": "rad:z4GypKmh1gkEfmkXtarcYnkvtFUfE", - "seeding": 0, + "seeding": 1, }, ]) ); @@ -898,7 +898,7 @@ mod routes { "closed": 0, }, "id": RID, - "seeding": 0, + "seeding": 1, }) ); } @@ -924,7 +924,7 @@ mod routes { "alias": CONTRIBUTOR_ALIAS } ], - "seeds": 0, + "seeds": 1, }, { "rid": "rad:z4GypKmh1gkEfmkXtarcYnkvtFUfE", @@ -937,7 +937,7 @@ mod routes { "alias": CONTRIBUTOR_ALIAS }, ], - "seeds": 0, + "seeds": 1, }, ]) ); @@ -964,7 +964,7 @@ mod routes { "alias": CONTRIBUTOR_ALIAS, } ], - "seeds": 0, + "seeds": 1, }, ]) ); diff --git a/radicle-httpd/src/api/v1/stats.rs b/radicle-httpd/src/api/v1/stats.rs index 388c8667b..aa740b430 100644 --- a/radicle-httpd/src/api/v1/stats.rs +++ b/radicle-httpd/src/api/v1/stats.rs @@ -4,7 +4,7 @@ use axum::routing::get; use axum::{Json, Router}; use serde_json::json; -use radicle::storage::ReadStorage; +use radicle::node::routing::Store; use crate::api::error::Error; use crate::api::Context; @@ -18,9 +18,12 @@ pub fn router(ctx: Context) -> Router { /// Return the stats for the node. /// `GET /stats` async fn stats_handler(State(ctx): State) -> impl IntoResponse { - let total = ctx.profile.storage.repositories()?.len(); + let db = &ctx.profile.database()?; + let nid = ctx.profile.public_key; - Ok::<_, Error>(Json(json!({ "repos": { "total": total } }))) + let total_seeded = db.get_inventory(&nid)?.len(); + + Ok::<_, Error>(Json(json!({ "repos": { "total": total_seeded } }))) } #[cfg(test)] @@ -37,6 +40,6 @@ mod routes { let response = get(&app, "/stats").await; assert_eq!(response.status(), StatusCode::OK); - assert_eq!(response.json().await, json!({ "repos": { "total": 3 } })); + assert_eq!(response.json().await, json!({ "repos": { "total": 2 } })); } } diff --git a/radicle-httpd/src/test.rs b/radicle-httpd/src/test.rs index c24310b1a..be267cc8e 100644 --- a/radicle-httpd/src/test.rs +++ b/radicle-httpd/src/test.rs @@ -7,6 +7,7 @@ use std::sync::Arc; use axum::body::{Body, Bytes}; use axum::http::{Method, Request}; use axum::Router; +use radicle::node::{Features, Timestamp, UserAgent}; use serde_json::Value; use tower::ServiceExt; @@ -17,8 +18,8 @@ use radicle::git::{raw as git2, RefString}; use radicle::identity::Visibility; use radicle::profile::{env, Home}; use radicle::storage::ReadStorage; -use radicle::Storage; use radicle::{node, profile}; +use radicle::{Node, Storage}; use radicle_crypto::test::signer::MockSigner; use crate::api::Context; @@ -52,6 +53,18 @@ pub fn profile(home: &Path, seed: [u8; 32]) -> radicle::Profile { let mut db = home.policies_mut().unwrap(); db.follow(&keypair.pk.into(), Some(&alias)).unwrap(); + let node_db = home.database_mut().unwrap(); + node_db + .init( + &keypair.pk.into(), + Features::SEED, + &alias, + &UserAgent::default(), + Timestamp::try_from(TIMESTAMP).unwrap(), + [], + ) + .unwrap(); + radicle::storage::git::transport::local::register(storage.clone()); keystore.store(keypair.clone(), "radicle", None).unwrap(); @@ -216,6 +229,11 @@ fn seed_with_signer(dir: &Path, profile: radicle::Profile, signer: &G ) .unwrap(); policies.seed(&rid, node::policy::Scope::All).unwrap(); + let node_handle = &mut Node::new(profile.socket()); + profile + .seed(rid, node::policy::Scope::All, node_handle) + .unwrap(); + profile.add_inventory(rid, node_handle).unwrap(); let storage = &profile.storage; let repo = storage.repository(rid).unwrap(); @@ -291,6 +309,10 @@ fn seed_with_signer(dir: &Path, profile: radicle::Profile, signer: &G ) .unwrap(); policies.seed(&rid, node::policy::Scope::Followed).unwrap(); + profile + .seed(rid, node::policy::Scope::Followed, node_handle) + .unwrap(); + profile.add_inventory(rid, node_handle).unwrap(); let options = crate::Options { aliases: std::collections::HashMap::new(),