rapiddb_web/api/v0/
sensor_meta.rs

1use crate::api::helpers::with_db;
2use rapiddb::traits::IAsyncDatabase;
3
4use warp::{Filter, Rejection, Reply};
5
6/// GET /api/v0/:String/meta
7pub fn get(
8  db: std::sync::Arc<tokio::sync::RwLock<impl IAsyncDatabase + ?Sized>>,
9) -> impl Filter<Extract = impl Reply, Error = Rejection> + Clone {
10  warp::path!("api" / "v0" / String / "meta")
11    .and(warp::get())
12    .and(with_db(db))
13    .and_then(_get)
14}
15
16pub async fn _get(
17  id: String,
18  db: std::sync::Arc<tokio::sync::RwLock<impl IAsyncDatabase + ?Sized>>,
19) -> Result<impl warp::Reply, std::convert::Infallible> {
20  let result = db.write().await.get_meta(&id).await;
21
22  if !result.is_empty() {
23    return Ok(
24      warp::hyper::Response::builder()
25        .status(warp::http::StatusCode::OK)
26        .body(result),
27    );
28  }
29
30  Ok(
31    warp::hyper::Response::builder()
32      .status(warp::http::StatusCode::NOT_FOUND)
33      .body(Default::default()),
34  )
35}
36
37/// POST /api/v0/:String/meta
38pub fn post(
39  db: std::sync::Arc<tokio::sync::RwLock<impl IAsyncDatabase + ?Sized>>,
40) -> impl Filter<Extract = impl Reply, Error = Rejection> + Clone {
41  warp::path!("api" / "v0" / String / "meta")
42    .and(warp::post())
43    .and(warp::body::content_length_limit(1024 * 16))
44    .and(warp::body::json())
45    .and(with_db(db))
46    .and_then(_post)
47}
48
49pub async fn _post(
50  id: String,
51  data: serde_json::Value,
52  db: std::sync::Arc<tokio::sync::RwLock<impl IAsyncDatabase + ?Sized>>,
53) -> Result<impl warp::Reply, std::convert::Infallible> {
54  db.write().await.post_meta(&id, data.to_string().as_bytes().to_vec()).await;
55
56  Ok(
57    warp::hyper::Response::builder()
58      .status(warp::http::StatusCode::ACCEPTED)
59      .body(""),
60  )
61}
62
63#[tokio::test]
64async fn test_get() {
65  let database_test_factory =
66    rapiddb::db::DatabaseTestFactory::new(".temp/test/sensor_meta/test_get");
67
68  for db in database_test_factory.get_instance().values() {
69    let api = super::endpoints((*db).clone());
70
71    let id = "test-0";
72
73    let resp = warp::test::request()
74      .method("GET")
75      .path(&format!("/api/v0/{id}/meta"))
76      .reply(&api)
77      .await;
78    assert_eq!(resp.status(), 404);
79
80    db.write()
81      .await
82      .post_meta(
83        id,
84        serde_json::json!({ "id": &id }).to_string().as_bytes().to_vec(),
85      )
86      .await;
87
88    let resp = warp::test::request()
89      .method("GET")
90      .path(&format!("/api/v0/{id}/meta"))
91      .reply(&api)
92      .await;
93    assert_eq!(resp.status(), 200);
94    assert_eq!(
95      serde_json::from_slice::<serde_json::Value>(resp.body()).unwrap(),
96      serde_json::json!({ "id": &id })
97    );
98
99    db.write()
100      .await
101      .post_meta(
102        id,
103        serde_json::json!({ "id0": &id }).to_string().as_bytes().to_vec(),
104      )
105      .await;
106
107    let resp = warp::test::request()
108      .method("GET")
109      .path(&format!("/api/v0/{id}/meta"))
110      .reply(&api)
111      .await;
112    assert_eq!(resp.status(), 200);
113    assert_eq!(
114      serde_json::from_slice::<serde_json::Value>(resp.body()).unwrap(),
115      serde_json::json!({ "id0": &id })
116    );
117  }
118}
119
120#[tokio::test]
121async fn test_post() {
122  let database_test_factory =
123    rapiddb::db::DatabaseTestFactory::new(".temp/test/sensor_meta/test_post");
124
125  for db in database_test_factory.get_instance().values() {
126    let api = super::endpoints((*db).clone());
127
128    let id = "test-0";
129
130    let resp = warp::test::request()
131      .method("POST")
132      .path(&format!("/api/v0/{id}/meta"))
133      .reply(&api)
134      .await;
135    assert_eq!(resp.status(), 411);
136
137    let resp = warp::test::request()
138      .method("POST")
139      .body(id)
140      .path(&format!("/api/v0/{id}/meta"))
141      .reply(&api)
142      .await;
143    assert_eq!(resp.status(), 400);
144
145    let resp = warp::test::request()
146      .method("POST")
147      .json(&serde_json::json!({ "id": &id }))
148      .path(&format!("/api/v0/{id}/meta"))
149      .reply(&api)
150      .await;
151    assert_eq!(resp.status(), 202);
152    assert_eq!(resp.body().len(), 0);
153
154    let id_db = db.write().await.get_meta(id).await;
155
156    assert_eq!(
157      id_db,
158      serde_json::json!({ "id": &id }).to_string().as_bytes().to_vec()
159    );
160  }
161}