httpd: Add api tests
Signed-off-by: xphoniex <dj.2dixx@gmail.com>
This commit is contained in:
parent
897d439f95
commit
7962ac0a8e
|
|
@ -2195,13 +2195,17 @@ dependencies = [
|
||||||
"hyper",
|
"hyper",
|
||||||
"lexopt",
|
"lexopt",
|
||||||
"radicle",
|
"radicle",
|
||||||
|
"radicle-cli",
|
||||||
|
"radicle-crypto",
|
||||||
"radicle-surf",
|
"radicle-surf",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"siwe",
|
"siwe",
|
||||||
|
"tempfile",
|
||||||
"thiserror",
|
"thiserror",
|
||||||
"time 0.3.17",
|
"time 0.3.17",
|
||||||
"tokio",
|
"tokio",
|
||||||
|
"tower",
|
||||||
"tower-http",
|
"tower-http",
|
||||||
"tracing",
|
"tracing",
|
||||||
"tracing-logfmt",
|
"tracing-logfmt",
|
||||||
|
|
|
||||||
|
|
@ -4,8 +4,7 @@ use std::ffi::OsString;
|
||||||
use anyhow::anyhow;
|
use anyhow::anyhow;
|
||||||
|
|
||||||
use radicle::crypto::ssh;
|
use radicle::crypto::ssh;
|
||||||
use radicle::profile;
|
use radicle::{profile, Profile};
|
||||||
use radicle::Profile;
|
|
||||||
|
|
||||||
use crate::git;
|
use crate::git;
|
||||||
use crate::terminal as term;
|
use crate::terminal as term;
|
||||||
|
|
|
||||||
|
|
@ -43,3 +43,10 @@ version = "0.2.0"
|
||||||
git = "https://github.com/radicle-dev/radicle-git"
|
git = "https://github.com/radicle-dev/radicle-git"
|
||||||
features = ["serde"]
|
features = ["serde"]
|
||||||
rev = "79a94721366490053e2d8ac1c1afa14fb0c25f09"
|
rev = "79a94721366490053e2d8ac1c1afa14fb0c25f09"
|
||||||
|
|
||||||
|
[dev-dependencies]
|
||||||
|
hyper = { version = "0.14.17", default-features = false, features = ["client"] }
|
||||||
|
radicle-cli = { path = "../radicle-cli" }
|
||||||
|
radicle-crypto = { path = "../radicle-crypto" }
|
||||||
|
tempfile = { version = "3.3.0" }
|
||||||
|
tower = { version = "0.4", features = ["util"] }
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,8 @@ use radicle::Profile;
|
||||||
mod auth;
|
mod auth;
|
||||||
mod axum_extra;
|
mod axum_extra;
|
||||||
mod error;
|
mod error;
|
||||||
|
#[cfg(test)]
|
||||||
|
mod test;
|
||||||
mod v1;
|
mod v1;
|
||||||
|
|
||||||
pub const VERSION: &str = env!("CARGO_PKG_VERSION");
|
pub const VERSION: &str = env!("CARGO_PKG_VERSION");
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,141 @@
|
||||||
|
use std::path::Path;
|
||||||
|
use std::sync::Arc;
|
||||||
|
use std::{env, fs};
|
||||||
|
|
||||||
|
use axum::body::Body;
|
||||||
|
use axum::http::Request;
|
||||||
|
use axum::Router;
|
||||||
|
use serde_json::Value;
|
||||||
|
use tower::ServiceExt;
|
||||||
|
|
||||||
|
use radicle::cob::issue::Issues;
|
||||||
|
use radicle::git::raw as git2;
|
||||||
|
use radicle::storage::WriteStorage;
|
||||||
|
use radicle_cli::commands::rad_init;
|
||||||
|
use radicle_crypto::ssh::keystore::MemorySigner;
|
||||||
|
use radicle_crypto::Signer;
|
||||||
|
|
||||||
|
use crate::api::Context;
|
||||||
|
|
||||||
|
pub const HEAD: &str = "1e978d19f251cd9821d9d9a76d1bd436bf0690d5";
|
||||||
|
pub const HEAD_1: &str = "f604ce9fd5b7cc77b7609beda45ea8760bee78f7";
|
||||||
|
|
||||||
|
const PASSWORD: &str = "radicle";
|
||||||
|
|
||||||
|
pub fn seed(dir: &Path) -> Context {
|
||||||
|
let workdir = dir.join("hello-world");
|
||||||
|
let rad_home = dir.join("radicle");
|
||||||
|
|
||||||
|
env::set_var("RAD_PASSPHRASE", PASSWORD);
|
||||||
|
env::set_var("RAD_DEBUG", "1");
|
||||||
|
|
||||||
|
fs::create_dir_all(&workdir).unwrap();
|
||||||
|
fs::create_dir_all(&rad_home).unwrap();
|
||||||
|
|
||||||
|
// add commits to workdir (repo)
|
||||||
|
let repo = git2::Repository::init(&workdir).unwrap();
|
||||||
|
let tree =
|
||||||
|
radicle::git::write_tree(Path::new("README"), "Hello World!\n".as_bytes(), &repo).unwrap();
|
||||||
|
|
||||||
|
let sig_time = git2::Time::new(1673001014, 0);
|
||||||
|
let sig = git2::Signature::new("Alice Liddell", "alice@radicle.xyz", &sig_time).unwrap();
|
||||||
|
|
||||||
|
let oid = repo
|
||||||
|
.commit(Some("HEAD"), &sig, &sig, "Initial commit\n", &tree, &[])
|
||||||
|
.unwrap();
|
||||||
|
let commit = repo.find_commit(oid).unwrap();
|
||||||
|
|
||||||
|
repo.checkout_tree(tree.as_object(), None).unwrap();
|
||||||
|
|
||||||
|
fs::create_dir(workdir.join("dir1")).unwrap();
|
||||||
|
fs::write(
|
||||||
|
workdir.join("dir1").join("README"),
|
||||||
|
"Hello World from dir1!\n",
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
let mut index = repo.index().unwrap();
|
||||||
|
index
|
||||||
|
.add_all(["."], git2::IndexAddOption::DEFAULT, None)
|
||||||
|
.unwrap();
|
||||||
|
index.write().unwrap();
|
||||||
|
|
||||||
|
let oid = index.write_tree().unwrap();
|
||||||
|
let tree = repo.find_tree(oid).unwrap();
|
||||||
|
|
||||||
|
repo.commit(
|
||||||
|
Some("HEAD"),
|
||||||
|
&sig,
|
||||||
|
&sig,
|
||||||
|
"Add another folder\n",
|
||||||
|
&tree,
|
||||||
|
&[&commit],
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
// eq. rad auth
|
||||||
|
let profile = radicle::Profile::init(rad_home, PASSWORD.to_owned()).unwrap();
|
||||||
|
|
||||||
|
// rad init
|
||||||
|
rad_init::init(
|
||||||
|
rad_init::Options {
|
||||||
|
path: Some(workdir.clone()),
|
||||||
|
name: Some("hello-world".to_string()),
|
||||||
|
description: Some("Rad repository for tests".to_string()),
|
||||||
|
branch: None,
|
||||||
|
interactive: false.into(),
|
||||||
|
setup_signing: false,
|
||||||
|
set_upstream: false,
|
||||||
|
},
|
||||||
|
&profile,
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
// eq. rad issue new
|
||||||
|
env::set_var("RAD_COMMIT_TIME", "1673001014");
|
||||||
|
|
||||||
|
let signer = MemorySigner::load(&profile.keystore, PASSWORD.to_owned().into()).unwrap();
|
||||||
|
let storage = &profile.storage;
|
||||||
|
let (_, id) = radicle::rad::repo(&workdir).unwrap();
|
||||||
|
let repo = storage.repository(id).unwrap();
|
||||||
|
let mut issues = Issues::open(*signer.public_key(), &repo).unwrap();
|
||||||
|
issues
|
||||||
|
.create(
|
||||||
|
"Issue #1".to_string(),
|
||||||
|
"Change 'hello world' to 'hello everyone'".to_string(),
|
||||||
|
&[],
|
||||||
|
&signer,
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
Context {
|
||||||
|
profile: Arc::new(profile),
|
||||||
|
sessions: Default::default(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn request(app: &Router, path: impl ToString) -> Response {
|
||||||
|
Response(
|
||||||
|
app.clone()
|
||||||
|
.oneshot(
|
||||||
|
Request::builder()
|
||||||
|
.uri(path.to_string())
|
||||||
|
.body(Body::empty())
|
||||||
|
.unwrap(),
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
.unwrap(),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct Response(axum::response::Response);
|
||||||
|
|
||||||
|
impl Response {
|
||||||
|
pub async fn json(self) -> Value {
|
||||||
|
let body = hyper::body::to_bytes(self.0.into_body()).await.unwrap();
|
||||||
|
serde_json::from_slice(&body).unwrap()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn status(&self) -> axum::http::StatusCode {
|
||||||
|
self.0.status()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -62,3 +62,38 @@ async fn delegates_projects_handler(
|
||||||
|
|
||||||
Ok::<_, Error>(Json(projects))
|
Ok::<_, Error>(Json(projects))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod routes {
|
||||||
|
use axum::http::StatusCode;
|
||||||
|
use serde_json::json;
|
||||||
|
|
||||||
|
use crate::api::test::{self, request, HEAD};
|
||||||
|
|
||||||
|
#[tokio::test]
|
||||||
|
async fn test_delegates_projects() {
|
||||||
|
let tmp = tempfile::tempdir().unwrap();
|
||||||
|
let app = super::router(test::seed(tmp.path()));
|
||||||
|
let response = request(
|
||||||
|
&app,
|
||||||
|
"/delegates/did:key:z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi/projects",
|
||||||
|
)
|
||||||
|
.await;
|
||||||
|
|
||||||
|
assert_eq!(response.status(), StatusCode::OK);
|
||||||
|
assert_eq!(
|
||||||
|
response.json().await,
|
||||||
|
json!([
|
||||||
|
{
|
||||||
|
"name": "hello-world",
|
||||||
|
"description": "Rad repository for tests",
|
||||||
|
"defaultBranch": "master",
|
||||||
|
"head": HEAD,
|
||||||
|
"patches": 0,
|
||||||
|
"issues": 1,
|
||||||
|
"id": "rad:z4FucBZHZMCsxTyQE1dfE2YR59Qbp"
|
||||||
|
}
|
||||||
|
])
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -467,3 +467,438 @@ fn stats(repo: &Repository, head: Oid) -> Result<Stats, Error> {
|
||||||
contributors: contributors.len(),
|
contributors: contributors.len(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod routes {
|
||||||
|
use axum::http::StatusCode;
|
||||||
|
use serde_json::json;
|
||||||
|
|
||||||
|
use crate::api::test::{self, request, HEAD, HEAD_1};
|
||||||
|
|
||||||
|
#[tokio::test]
|
||||||
|
async fn test_projects_root() {
|
||||||
|
let tmp = tempfile::tempdir().unwrap();
|
||||||
|
let app = super::router(test::seed(tmp.path()));
|
||||||
|
let response = request(&app, "/projects").await;
|
||||||
|
|
||||||
|
assert_eq!(response.status(), StatusCode::OK);
|
||||||
|
assert_eq!(
|
||||||
|
response.json().await,
|
||||||
|
json!([
|
||||||
|
{
|
||||||
|
"name": "hello-world",
|
||||||
|
"description": "Rad repository for tests",
|
||||||
|
"defaultBranch": "master",
|
||||||
|
"head": HEAD,
|
||||||
|
"patches": 0,
|
||||||
|
"issues": 1,
|
||||||
|
"id": "rad:z4FucBZHZMCsxTyQE1dfE2YR59Qbp"
|
||||||
|
}
|
||||||
|
])
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[tokio::test]
|
||||||
|
async fn test_projects() {
|
||||||
|
let tmp = tempfile::tempdir().unwrap();
|
||||||
|
let app = super::router(test::seed(tmp.path()));
|
||||||
|
let response = request(&app, "/projects/rad:z4FucBZHZMCsxTyQE1dfE2YR59Qbp").await;
|
||||||
|
|
||||||
|
assert_eq!(response.status(), StatusCode::OK);
|
||||||
|
assert_eq!(
|
||||||
|
response.json().await,
|
||||||
|
json!({
|
||||||
|
"name": "hello-world",
|
||||||
|
"description": "Rad repository for tests",
|
||||||
|
"defaultBranch": "master",
|
||||||
|
"head": HEAD,
|
||||||
|
"patches": 0,
|
||||||
|
"issues": 1,
|
||||||
|
"id": "rad:z4FucBZHZMCsxTyQE1dfE2YR59Qbp"
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[tokio::test]
|
||||||
|
async fn test_projects_commits_root() {
|
||||||
|
let tmp = tempfile::tempdir().unwrap();
|
||||||
|
let app = super::router(test::seed(tmp.path()));
|
||||||
|
let response = request(&app, "/projects/rad:z4FucBZHZMCsxTyQE1dfE2YR59Qbp/commits").await;
|
||||||
|
|
||||||
|
assert_eq!(response.status(), StatusCode::FOUND);
|
||||||
|
assert_eq!(
|
||||||
|
response.json().await,
|
||||||
|
json!({
|
||||||
|
"headers": [
|
||||||
|
{
|
||||||
|
"header": {
|
||||||
|
"sha1": HEAD,
|
||||||
|
"author": {
|
||||||
|
"name": "Alice Liddell",
|
||||||
|
"email": "alice@radicle.xyz"
|
||||||
|
},
|
||||||
|
"summary": "Add another folder",
|
||||||
|
"description": "",
|
||||||
|
"committer": {
|
||||||
|
"name": "Alice Liddell",
|
||||||
|
"email": "alice@radicle.xyz"
|
||||||
|
},
|
||||||
|
"committerTime": 1673001014
|
||||||
|
},
|
||||||
|
"diff": {
|
||||||
|
"added": [
|
||||||
|
{
|
||||||
|
"path": "dir1/README",
|
||||||
|
"diff": {
|
||||||
|
"type": "plain",
|
||||||
|
"hunks": [
|
||||||
|
{
|
||||||
|
"header": "@@ -0,0 +1 @@\n",
|
||||||
|
"lines": [
|
||||||
|
{
|
||||||
|
"line": "Hello World from dir1!\n",
|
||||||
|
"lineNo": 1,
|
||||||
|
"type": "addition"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"deleted": [],
|
||||||
|
"moved": [],
|
||||||
|
"copied": [],
|
||||||
|
"modified": [],
|
||||||
|
"stats": {
|
||||||
|
"filesChanged": 1,
|
||||||
|
"insertions": 1,
|
||||||
|
"deletions": 0
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"branches": [
|
||||||
|
"refs/heads/master"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"header": {
|
||||||
|
"sha1": HEAD_1,
|
||||||
|
"author": {
|
||||||
|
"name": "Alice Liddell",
|
||||||
|
"email": "alice@radicle.xyz"
|
||||||
|
},
|
||||||
|
"summary": "Initial commit",
|
||||||
|
"description": "",
|
||||||
|
"committer": {
|
||||||
|
"name": "Alice Liddell",
|
||||||
|
"email": "alice@radicle.xyz"
|
||||||
|
},
|
||||||
|
"committerTime": 1673001014
|
||||||
|
},
|
||||||
|
"diff": {
|
||||||
|
"added": [
|
||||||
|
{
|
||||||
|
"path": "README",
|
||||||
|
"diff": {
|
||||||
|
"type": "plain",
|
||||||
|
"hunks": [
|
||||||
|
{
|
||||||
|
"header": "@@ -0,0 +1 @@\n",
|
||||||
|
"lines": [
|
||||||
|
{
|
||||||
|
"line": "Hello World!\n",
|
||||||
|
"lineNo": 1,
|
||||||
|
"type": "addition"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"deleted": [],
|
||||||
|
"moved": [],
|
||||||
|
"copied": [],
|
||||||
|
"modified": [],
|
||||||
|
"stats": {
|
||||||
|
"filesChanged": 1,
|
||||||
|
"insertions": 1,
|
||||||
|
"deletions": 0
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"branches": [
|
||||||
|
"refs/heads/master"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"stats": {
|
||||||
|
"commits": 2,
|
||||||
|
"branches": 1,
|
||||||
|
"contributors": 1
|
||||||
|
}
|
||||||
|
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[tokio::test]
|
||||||
|
async fn test_projects_commits() {
|
||||||
|
let tmp = tempfile::tempdir().unwrap();
|
||||||
|
let app = super::router(test::seed(tmp.path()));
|
||||||
|
let response = request(
|
||||||
|
&app,
|
||||||
|
format!("/projects/rad:z4FucBZHZMCsxTyQE1dfE2YR59Qbp/commits/{HEAD}"),
|
||||||
|
)
|
||||||
|
.await;
|
||||||
|
|
||||||
|
assert_eq!(response.status(), StatusCode::OK);
|
||||||
|
assert_eq!(
|
||||||
|
response.json().await,
|
||||||
|
json!({
|
||||||
|
"header": {
|
||||||
|
"sha1": HEAD,
|
||||||
|
"author": {
|
||||||
|
"name": "Alice Liddell",
|
||||||
|
"email": "alice@radicle.xyz"
|
||||||
|
},
|
||||||
|
"summary": "Add another folder",
|
||||||
|
"description": "",
|
||||||
|
"committer": {
|
||||||
|
"name": "Alice Liddell",
|
||||||
|
"email": "alice@radicle.xyz"
|
||||||
|
},
|
||||||
|
"committerTime": 1673001014
|
||||||
|
},
|
||||||
|
"diff": {
|
||||||
|
"added": [
|
||||||
|
{
|
||||||
|
"path": "dir1/README",
|
||||||
|
"diff": {
|
||||||
|
"type": "plain",
|
||||||
|
"hunks": [
|
||||||
|
{
|
||||||
|
"header": "@@ -0,0 +1 @@\n",
|
||||||
|
"lines": [
|
||||||
|
{
|
||||||
|
"line": "Hello World from dir1!\n",
|
||||||
|
"lineNo": 1,
|
||||||
|
"type": "addition"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"deleted": [],
|
||||||
|
"moved": [],
|
||||||
|
"copied": [],
|
||||||
|
"modified": [],
|
||||||
|
"stats": {
|
||||||
|
"filesChanged": 1,
|
||||||
|
"insertions": 1,
|
||||||
|
"deletions": 0
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"branches": [
|
||||||
|
"refs/heads/master"
|
||||||
|
]
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[tokio::test]
|
||||||
|
async fn test_projects_tree() {
|
||||||
|
let tmp = tempfile::tempdir().unwrap();
|
||||||
|
let app = super::router(test::seed(tmp.path()));
|
||||||
|
let response = request(
|
||||||
|
&app,
|
||||||
|
format!("/projects/rad:z4FucBZHZMCsxTyQE1dfE2YR59Qbp/tree/{HEAD}/"),
|
||||||
|
)
|
||||||
|
.await;
|
||||||
|
|
||||||
|
assert_eq!(response.status(), StatusCode::OK);
|
||||||
|
assert_eq!(
|
||||||
|
response.json().await,
|
||||||
|
json!({
|
||||||
|
"entries": [
|
||||||
|
{
|
||||||
|
"path": "README",
|
||||||
|
"name": "README",
|
||||||
|
"lastCommit": null,
|
||||||
|
"kind": "blob"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "dir1",
|
||||||
|
"name": "dir1",
|
||||||
|
"lastCommit": null,
|
||||||
|
"kind": "tree"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"lastCommit": {
|
||||||
|
"sha1": HEAD,
|
||||||
|
"author": {
|
||||||
|
"name": "Alice Liddell",
|
||||||
|
"email": "alice@radicle.xyz"
|
||||||
|
},
|
||||||
|
"summary": "Add another folder",
|
||||||
|
"description": "",
|
||||||
|
"committer": {
|
||||||
|
"name": "Alice Liddell",
|
||||||
|
"email": "alice@radicle.xyz"
|
||||||
|
},
|
||||||
|
"committerTime": 1673001014
|
||||||
|
},
|
||||||
|
"name": "",
|
||||||
|
"path": "",
|
||||||
|
"stats": {
|
||||||
|
"branches": 1,
|
||||||
|
"commits": 2,
|
||||||
|
"contributors": 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
let response = request(
|
||||||
|
&app,
|
||||||
|
format!("/projects/rad:z4FucBZHZMCsxTyQE1dfE2YR59Qbp/tree/{HEAD}/dir1"),
|
||||||
|
)
|
||||||
|
.await;
|
||||||
|
|
||||||
|
assert_eq!(response.status(), StatusCode::OK);
|
||||||
|
assert_eq!(
|
||||||
|
response.json().await,
|
||||||
|
json!({
|
||||||
|
"entries": [
|
||||||
|
{
|
||||||
|
"path": "dir1/README",
|
||||||
|
"name": "README",
|
||||||
|
"lastCommit": null,
|
||||||
|
"kind": "blob"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"lastCommit": null,
|
||||||
|
"name": "dir1",
|
||||||
|
"path": "dir1",
|
||||||
|
"stats": {
|
||||||
|
"branches": 1,
|
||||||
|
"commits": 2,
|
||||||
|
"contributors": 1
|
||||||
|
}
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[tokio::test]
|
||||||
|
async fn test_projects_remotes_root() {
|
||||||
|
let tmp = tempfile::tempdir().unwrap();
|
||||||
|
let app = super::router(test::seed(tmp.path()));
|
||||||
|
let response = request(&app, "/projects/rad:z4FucBZHZMCsxTyQE1dfE2YR59Qbp/remotes").await;
|
||||||
|
|
||||||
|
assert_eq!(response.status(), StatusCode::OK);
|
||||||
|
assert_eq!(
|
||||||
|
response.json().await,
|
||||||
|
json!([
|
||||||
|
{
|
||||||
|
"id": "z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi",
|
||||||
|
"heads": {
|
||||||
|
"master": HEAD
|
||||||
|
},
|
||||||
|
"delegate": false
|
||||||
|
}
|
||||||
|
])
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[tokio::test]
|
||||||
|
async fn test_projects_remotes() {
|
||||||
|
let tmp = tempfile::tempdir().unwrap();
|
||||||
|
let app = super::router(test::seed(tmp.path()));
|
||||||
|
let response = request(&app, "/projects/rad:z4FucBZHZMCsxTyQE1dfE2YR59Qbp/remotes/z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi").await;
|
||||||
|
|
||||||
|
assert_eq!(response.status(), StatusCode::OK);
|
||||||
|
assert_eq!(
|
||||||
|
response.json().await,
|
||||||
|
json!({
|
||||||
|
"id": "z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi",
|
||||||
|
"heads": {
|
||||||
|
"master": HEAD
|
||||||
|
},
|
||||||
|
"delegate": false
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[tokio::test]
|
||||||
|
async fn test_projects_blob() {
|
||||||
|
let tmp = tempfile::tempdir().unwrap();
|
||||||
|
let app = super::router(test::seed(tmp.path()));
|
||||||
|
let response = request(
|
||||||
|
&app,
|
||||||
|
format!("/projects/rad:z4FucBZHZMCsxTyQE1dfE2YR59Qbp/blob/{HEAD}/README"),
|
||||||
|
)
|
||||||
|
.await;
|
||||||
|
|
||||||
|
assert_eq!(response.status(), StatusCode::OK);
|
||||||
|
assert_eq!(
|
||||||
|
response.json().await,
|
||||||
|
json!({
|
||||||
|
"binary": false,
|
||||||
|
"content": "Hello World!\n",
|
||||||
|
"lastCommit": {
|
||||||
|
"sha1": HEAD_1,
|
||||||
|
"author": {
|
||||||
|
"name": "Alice Liddell",
|
||||||
|
"email": "alice@radicle.xyz"
|
||||||
|
},
|
||||||
|
"summary": "Initial commit",
|
||||||
|
"description": "",
|
||||||
|
"committer": {
|
||||||
|
"name": "Alice Liddell",
|
||||||
|
"email": "alice@radicle.xyz"
|
||||||
|
},
|
||||||
|
"committerTime": 1673001014
|
||||||
|
},
|
||||||
|
"name": "README",
|
||||||
|
"path": "README"
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[tokio::test]
|
||||||
|
async fn test_projects_issues_root() {
|
||||||
|
let tmp = tempfile::tempdir().unwrap();
|
||||||
|
let app = super::router(test::seed(tmp.path()));
|
||||||
|
let response = request(&app, "/projects/rad:z4FucBZHZMCsxTyQE1dfE2YR59Qbp/issues").await;
|
||||||
|
|
||||||
|
assert_eq!(response.status(), StatusCode::OK);
|
||||||
|
assert_eq!(
|
||||||
|
response.json().await,
|
||||||
|
json!([
|
||||||
|
{
|
||||||
|
"id": "458bbd9f6d47eed3d60cd905141687ad1f99251e",
|
||||||
|
"author": {
|
||||||
|
"id": "z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi"
|
||||||
|
},
|
||||||
|
"title": "Issue #1",
|
||||||
|
"state": {
|
||||||
|
"status": "open"
|
||||||
|
},
|
||||||
|
"discussion": [
|
||||||
|
{
|
||||||
|
"author": {
|
||||||
|
"id": "z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi"
|
||||||
|
},
|
||||||
|
"body": "Change 'hello world' to 'hello everyone'",
|
||||||
|
"reactions": [],
|
||||||
|
"timestamp": 1673001014,
|
||||||
|
"replyTo": null
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"tags": []
|
||||||
|
}
|
||||||
|
])
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -22,3 +22,31 @@ async fn stats_handler(Extension(ctx): Extension<Context>) -> impl IntoResponse
|
||||||
json!({ "projects": { "count": projects }, "users": { "count": 0 } }),
|
json!({ "projects": { "count": projects }, "users": { "count": 0 } }),
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod routes {
|
||||||
|
use axum::http::StatusCode;
|
||||||
|
use serde_json::json;
|
||||||
|
|
||||||
|
use crate::api::test::{self, request};
|
||||||
|
|
||||||
|
#[tokio::test]
|
||||||
|
async fn test_stats() {
|
||||||
|
let tmp = tempfile::tempdir().unwrap();
|
||||||
|
let app = super::router(test::seed(tmp.path()));
|
||||||
|
let response = request(&app, "/stats").await;
|
||||||
|
|
||||||
|
assert_eq!(response.status(), StatusCode::OK);
|
||||||
|
assert_eq!(
|
||||||
|
response.json().await,
|
||||||
|
json!({
|
||||||
|
"projects": {
|
||||||
|
"count": 1
|
||||||
|
},
|
||||||
|
"users": {
|
||||||
|
"count": 0
|
||||||
|
}
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue