Skip to content

Commit

Permalink
feat(httpd): implement the show endpoint
Browse files Browse the repository at this point in the history
This commit:
1- define a new type Show to send to the show http endpoint
2- implement coffee_show function to handle /show endpoint
3- add an httpd integration test to further stress test the server. The new test mimics a test case where all endpoints are called.

Signed-off-by: Tarek <tareknaser360@gmail.com>
  • Loading branch information
tareknaser committed Jul 19, 2023
1 parent 17a2f90 commit 1656a78
Show file tree
Hide file tree
Showing 3 changed files with 265 additions and 0 deletions.
22 changes: 22 additions & 0 deletions coffee_httpd/src/httpd/server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ pub async fn run_httpd<T: ToSocketAddrs>(
.service(coffee_remote_add)
.service(coffee_remote_rm)
.service(coffee_remote_list)
.service(coffee_show)
.with_json_spec_at("/api/v1")
.build()
})
Expand Down Expand Up @@ -178,6 +179,27 @@ async fn coffee_remote_list(data: web::Data<AppState>) -> Result<Json<Value>, Er
}
}

#[api_v2_operation]
#[get("/show")]
async fn coffee_show(data: web::Data<AppState>, body: Json<Show>) -> Result<Json<Value>, Error> {
let plugin = &body.plugin;

let mut coffee = data.coffee.lock().await;
let result = coffee.show(plugin).await;

match result {
Ok(coffee_show) => {
let val = serde_json::to_value(coffee_show).map_err(|err| {
actix_web::error::ErrorInternalServerError(format!("Failure: {err}"))
})?;
Ok(Json(val))
}
Err(err) => Err(actix_web::error::ErrorInternalServerError(format!(
"Failure: {err}"
))),
}
}

// this is just a hack to support swagger UI with https://paperclip-rs.github.io/paperclip/
// and the raw html is taken from https://github.com/swagger-api/swagger-ui/blob/master/docs/usage/installation.md#unpkg
#[get("/")]
Expand Down
5 changes: 5 additions & 0 deletions coffee_lib/src/types/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,11 @@ pub mod request {
pub struct RemoteRm {
pub repository_name: String,
}

#[derive(Debug, Deserialize, Apiv2Schema, Serialize)]
pub struct Show {
pub plugin: String,
}
}

// Definition of the response types.
Expand Down
238 changes: 238 additions & 0 deletions tests/src/coffee_httpd_integration_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,3 +67,241 @@ pub async fn httpd_init_add_remote() {

cln.stop().await.unwrap();
}

#[tokio::test(flavor = "multi_thread")]
#[ntest::timeout(560000)]
pub async fn httpd_add_remove_plugins() {
init();

let mut cln = Node::tmp("regtest").await.unwrap();
let lightning_dir = cln.rpc().getinfo().unwrap().ligthning_dir;
let lightning_dir = lightning_dir.strip_suffix("/regtest").unwrap();
let manager = CoffeeHTTPDTesting::tmp(lightning_dir.to_string())
.await
.unwrap();
log::info!("lightning path: {lightning_dir}");
let url = manager.url();
log::info!("base url: {url}");
let client = reqwest::Client::new();

// Define the request body to be sent to the /remote/add endpoint
let remote_add_request = RemoteAdd {
repository_name: "lightningd".to_string(),
repository_url: "https://github.com/lightningd/plugins.git".to_string(),
};

// Send the request to add a remote repository
let response = client
.post(format!("{}/remote/add", url))
.json(&remote_add_request)
.send()
.await
.unwrap();

// Check the response status code, log the body.
assert!(response.status().is_success());
let body = response.text().await.unwrap();
log::info!("/remote/add response: {}", body);

// Define the request body to be sent to the /show endpoint
let show_request = Show {
plugin: "helpme".to_string(),
};

// Send a get request to the /show endpoint
let response = client
.get(format!("{}/show", url))
.json(&show_request)
.send()
.await
.unwrap();

// Check the response status code, log the body.
assert!(response.status().is_success());
let body = response.text().await.unwrap();
log::info!("/show response: {}", body);

// Parse the response body
let response_json: serde_json::Value = serde_json::from_str(&body).unwrap();

// Extract the `readme` field from the response JSON
let readme = response_json["readme"].as_str().unwrap();

// Assert that the `readme` starts with the expected content
assert!(readme.starts_with("# Helpme plugin"));

// Define the request body to be sent to the /install endpoint
let install_request = Install {
plugin: "summary".to_string(),
try_dynamic: false,
};

// Send the request to install "summary" plugin
let response = client
.post(format!("{}/install", url))
.json(&install_request)
.send()
.await
.unwrap();

// Check the response status code, log the body.
let body = response.text().await.unwrap();
log::info!("/install response: {}", body);

// Define the request body to be sent to the /install endpoint
let install_request = Install {
plugin: "helpme".to_string(),
try_dynamic: false,
};

// Send the request to install "helpme" plugin
let response = client
.post(format!("{}/install", url))
.json(&install_request)
.send()
.await
.unwrap();

// Check the response status code, log the body.
let body = response.text().await.unwrap();
log::info!("/install response: {}", body);

// Send a request to the /remote/list endpoint to
// ensure that the list of remotes is correct
let body = reqwest::get(format!("{}/remote/list", url))
.await
.unwrap()
.json::<serde_json::Value>()
.await
.unwrap();

// Log the response body
log::info!("/remote/list response: {}", body);

// Assert that the "lightningd" remote repository exists in the response
let remotes = body["remotes"].as_array().unwrap();
assert!(
remotes
.iter()
.any(|repo| repo["local_name"] == "lightningd"),
"lightningd remote repository not found in the response"
);

// Send a get request to the list endpoint
let body = reqwest::get(format!("{}/list", url))
.await
.unwrap()
.json::<serde_json::Value>()
.await
.unwrap();

// Log the response body
log::info!("/list response: {}", body);

// Assert that the "helpme" and "summary" plugin exist in the response
let plugins = body["plugins"].as_array().unwrap();
assert!(
plugins.iter().any(|plugin| plugin["name"] == "helpme"),
"helpme plugin not found in the response"
);
assert!(
plugins.iter().any(|plugin| plugin["name"] == "summary"),
"summary plugin not found in the response"
);

// Define the request body to be sent
let plugin_remove_request = Remove {
plugin: "summary".to_string(),
};

// Send the request to remove a plugin
let response = client
.post(format!("{}/remove", url))
.json(&plugin_remove_request)
.send()
.await
.unwrap();

// Check the response status code, log the body.
assert!(response.status().is_success());
let body = response.text().await.unwrap();
log::info!("Response body: {}", body);

// Send a get request to the list endpoint
let body = reqwest::get(format!("{}/list", url))
.await
.unwrap()
.json::<serde_json::Value>()
.await
.unwrap();

// Log the response body
log::info!("/list response: {}", body);

// Assert that the "summary" plugin was removed
let plugins = body["plugins"].as_array().unwrap();
assert!(
!plugins.iter().any(|plugin| plugin["name"] == "summary"),
"summary plugin is found in the list response while it should have been removed"
);

// Define the request body to be sent
let remote_rm_request = RemoteRm {
repository_name: "lightningd".to_string(),
};

// Send the request to remove a remote repository
// This should also remove the helpme plugin
let response = client
.post(format!("{}/remote/rm", url))
.json(&remote_rm_request)
.send()
.await
.unwrap();

// Check the response status code, log the body.
assert!(response.status().is_success());
let body = response.text().await.unwrap();
log::info!("/remote/rm response: {}", body);

// Send a get request to the list endpoint
let body = reqwest::get(format!("{}/list", url))
.await
.unwrap()
.json::<serde_json::Value>()
.await
.unwrap();

// Log the response body
log::info!("/list response: {}", body);

// Assert that the "helpme" plugin was removed
let plugins = body["plugins"].as_array().unwrap();
assert!(
!plugins.iter().any(|plugin| plugin["name"] == "helpme"),
"helpme plugin is found in the list response while it should have been removed"
);

// Send a request to the /remote/list endpoint to
// ensure that the list of remotes is correct
let body = reqwest::get(format!("{}/remote/list", url))
.await
.unwrap()
.json::<serde_json::Value>()
.await
.unwrap();

// Log the response body
log::info!("/remote/list response: {}", body);

// Assert that the "lightningd" remote repository doesn't exist in the response
let remotes = body["remotes"].as_array().unwrap();
assert!(
!remotes
.iter()
.any(|repo| repo["local_name"] == "lightningd"),
"lightningd remote repository is found in the response while it should have been removed"
);

cln.stop().await.unwrap();
}

0 comments on commit 1656a78

Please sign in to comment.