Files
upstream-mirror da934b693c
Some checks failed
Build / ubuntu-latest (push) Failing after 5s
Build / Android (push) Failing after 2s
Build / Code coverage (push) Failing after 2s
Lint / format (push) Failing after 3s
Lint / clippy (push) Failing after 3s
Build / macOS-latest (push) Has been cancelled
Build / windows-latest (push) Has been cancelled
snapshot of https://github.com/ActivityWatch/aw-server-rust.git (master, 2026-09-16; blobs > 131072B omitted)
2026-09-16 00:19:17 +05:00

915 lines
32 KiB
Rust

extern crate log;
extern crate rocket;
extern crate aw_datastore;
extern crate aw_server;
#[cfg(test)]
mod api_tests {
use std::collections::HashMap;
use rocket::http::{ContentType, Header, Status};
use serde_json::{json, Value};
use aw_server::config;
use aw_server::endpoints;
use aw_models::{Bucket, BucketsExport};
use rocket::local::blocking::Client;
fn setup_testserver() -> rocket::Rocket<rocket::Build> {
let state = endpoints::ServerState {
datastore: aw_datastore::Datastore::new_in_memory(false),
asset_resolver: endpoints::AssetResolver::new(None),
device_id: "test_id".to_string(),
};
let aw_config = config::AWConfig::default();
endpoints::build_rocket(state, aw_config)
}
#[test]
fn export_includes_pending_writes_and_preserves_headers_and_missing_bucket_errors() {
let server = setup_testserver();
let datastore = server
.state::<endpoints::ServerState>()
.unwrap()
.datastore
.clone();
let bucket: Bucket = serde_json::from_value(json!({
"id": "live", "type": "test", "client": "test", "hostname": "test"
}))
.unwrap();
datastore.create_bucket(&bucket).unwrap();
let event = aw_models::Event::default();
let inserted = datastore.insert_events("live", &[event]).unwrap();
// No force_commit: exports must see writes acknowledged by the worker.
let client = Client::untracked(server).unwrap();
for path in ["/api/0/export", "/api/0/buckets/live/export"] {
let response = client
.get(path)
.header(Header::new("Host", "127.0.0.1:5600"))
.dispatch();
assert_eq!(response.status(), Status::Ok);
assert_eq!(response.content_type(), Some(ContentType::JSON));
assert_eq!(
response.headers().get_one("Content-Disposition"),
Some("attachment; filename=aw-bucket-export_live.json")
);
let body: Value = serde_json::from_str(&response.into_string().unwrap()).unwrap();
assert_eq!(
body["buckets"]["live"]["events"],
serde_json::to_value(&inserted).unwrap()
);
}
let response = client
.get("/api/0/buckets/missing/export")
.header(Header::new("Host", "127.0.0.1:5600"))
.dispatch();
assert_eq!(response.status(), Status::NotFound);
let body: Value = serde_json::from_str(&response.into_string().unwrap()).unwrap();
assert!(body["message"].as_str().unwrap().contains("does not exist"));
}
#[test]
fn test_bucket() {
let server = setup_testserver();
let client = Client::untracked(server).expect("valid instance");
// Get empty list of buckets
let mut res = client
.get("/api/0/buckets/")
.header(ContentType::JSON)
.header(Header::new("Host", "127.0.0.1:5600"))
.dispatch();
assert_eq!(res.status(), rocket::http::Status::Ok);
let buckets: HashMap<String, Bucket> =
serde_json::from_str(&res.into_string().unwrap()).unwrap();
assert_eq!(buckets.len(), 0);
// Try to fetch non-existing bucket
res = client
.get("/api/0/buckets/id")
.header(ContentType::JSON)
.header(Header::new("Host", "127.0.0.1:5600"))
.dispatch();
assert_eq!(res.status(), rocket::http::Status::NotFound);
// Create bucket
res = client
.post("/api/0/buckets/id")
.header(ContentType::JSON)
.header(Header::new("Host", "127.0.0.1:5600"))
.body(
r#"{
"id": "id",
"type": "type",
"client": "client",
"hostname": "hostname"
}"#,
)
.dispatch();
assert_eq!(res.status(), rocket::http::Status::Ok);
// Try to create bucket which already exists
res = client
.post("/api/0/buckets/id")
.header(ContentType::JSON)
.header(Header::new("Host", "127.0.0.1:5600"))
.body(
r#"{
"id": "id",
"type": "type",
"client": "client",
"hostname": "hostname"
}"#,
)
.dispatch();
assert_eq!(res.status(), rocket::http::Status::NotModified);
assert_eq!(
res.into_string().unwrap(),
r#"{"message":"Bucket 'id' already exists"}"#
);
// Get list of buckets (1 bucket)
res = client
.get("/api/0/buckets/")
.header(ContentType::JSON)
.header(Header::new("Host", "127.0.0.1:5600"))
.dispatch();
assert_eq!(res.status(), rocket::http::Status::Ok);
let buckets: HashMap<String, Bucket> =
serde_json::from_str(&res.into_string().unwrap()).unwrap();
assert_eq!(buckets.len(), 1);
let bucket = buckets.get("id").unwrap();
assert_eq!(bucket.id, "id");
assert_eq!(bucket._type, "type");
assert_eq!(bucket.client, "client");
assert_eq!(bucket.hostname, "hostname");
assert!(bucket.events.is_none());
assert_eq!(bucket.metadata.start, None);
assert_eq!(bucket.metadata.end, None);
// Get newly created bucket
res = client
.get("/api/0/buckets/id")
.header(ContentType::JSON)
.header(Header::new("Host", "127.0.0.1:5600"))
.dispatch();
assert_eq!(res.status(), rocket::http::Status::Ok);
// Validate output
let bucket: Bucket = serde_json::from_str(&res.into_string().unwrap()).unwrap();
assert_eq!(bucket.id, "id");
assert_eq!(bucket._type, "type");
assert_eq!(bucket.client, "client");
assert_eq!(bucket.hostname, "hostname");
assert!(bucket.events.is_none());
assert_eq!(bucket.metadata.start, None);
assert_eq!(bucket.metadata.end, None);
// Get non-existing bucket
res = client
.get("/api/0/buckets/invalid_bucket")
.header(ContentType::JSON)
.header(Header::new("Host", "127.0.0.1:5600"))
.dispatch();
assert_eq!(res.status(), rocket::http::Status::NotFound);
// Delete bucket
res = client
.delete("/api/0/buckets/id")
.header(ContentType::JSON)
.header(Header::new("Host", "127.0.0.1:5600"))
.dispatch();
assert_eq!(res.status(), rocket::http::Status::Ok);
// Try (and fail) to get deleted bucket
res = client
.get("/api/0/buckets/id")
.header(ContentType::JSON)
.header(Header::new("Host", "127.0.0.1:5600"))
.dispatch();
assert_eq!(res.status(), rocket::http::Status::NotFound);
// Get empty list of buckets
let res = client
.get("/api/0/buckets/")
.header(ContentType::JSON)
.header(Header::new("Host", "127.0.0.1:5600"))
.dispatch();
assert_eq!(res.status(), rocket::http::Status::Ok);
let buckets: HashMap<String, Bucket> =
serde_json::from_str(&res.into_string().unwrap()).unwrap();
assert_eq!(buckets.len(), 0);
}
#[test]
fn test_bucket_hostname_validation() {
let server = setup_testserver();
let client = Client::untracked(server).expect("valid instance");
// A client-supplied hostname containing whitespace is rejected
let res = client
.post("/api/0/buckets/spacey")
.header(ContentType::JSON)
.header(Header::new("Host", "127.0.0.1:5600"))
.body(
r#"{
"id": "spacey",
"type": "type",
"client": "client",
"hostname": "my phone"
}"#,
)
.dispatch();
assert_eq!(res.status(), rocket::http::Status::BadRequest);
assert_eq!(
res.into_string().unwrap(),
r#"{"message":"Invalid hostname \"my phone\": hostname may not contain whitespace"}"#
);
// The rejected bucket was not created
let res = client
.get("/api/0/buckets/spacey")
.header(ContentType::JSON)
.header(Header::new("Host", "127.0.0.1:5600"))
.dispatch();
assert_eq!(res.status(), rocket::http::Status::NotFound);
// An already-existing bucket keeps the established "already exists" response
// even if the re-create payload carries a whitespace hostname. Watchers
// idempotently re-create their bucket on startup, so a legacy bucket stored
// under a spacey hostname must not start hard-failing every boot.
let res = client
.post("/api/0/buckets/existing")
.header(ContentType::JSON)
.header(Header::new("Host", "127.0.0.1:5600"))
.body(
r#"{
"id": "existing",
"type": "type",
"client": "client",
"hostname": "hostname"
}"#,
)
.dispatch();
assert_eq!(res.status(), rocket::http::Status::Ok);
let res = client
.post("/api/0/buckets/existing")
.header(ContentType::JSON)
.header(Header::new("Host", "127.0.0.1:5600"))
.body(
r#"{
"id": "existing",
"type": "type",
"client": "client",
"hostname": "my phone"
}"#,
)
.dispatch();
assert_eq!(res.status(), rocket::http::Status::NotModified);
// The "!local" sentinel bypasses validation (resolved server-side)
let res = client
.post("/api/0/buckets/localbucket")
.header(ContentType::JSON)
.header(Header::new("Host", "127.0.0.1:5600"))
.body(
r#"{
"id": "localbucket",
"type": "type",
"client": "client",
"hostname": "!local"
}"#,
)
.dispatch();
assert_eq!(res.status(), rocket::http::Status::Ok);
}
#[test]
fn test_events() {
let server = setup_testserver();
let client = Client::untracked(server).expect("valid instance");
// Create bucket
let res = client
.post("/api/0/buckets/id")
.header(ContentType::JSON)
.header(Header::new("Host", "127.0.0.1:5600"))
.body(
r#"{
"id": "id",
"type": "type",
"client": "client",
"hostname": "hostname"
}"#,
)
.dispatch();
assert_eq!(res.status(), rocket::http::Status::Ok);
// Insert a single event
let res = client
.post("/api/0/buckets/id/events")
.header(ContentType::JSON)
.header(Header::new("Host", "127.0.0.1:5600"))
.body(
r#"[{
"timestamp": "2018-01-01T01:01:01Z",
"duration": 1.0,
"data": {}
}]"#,
)
.dispatch();
assert_eq!(res.status(), rocket::http::Status::Ok);
assert_eq!(
res.into_string().unwrap(),
r#"[{"id":1,"timestamp":"2018-01-01T01:01:01Z","duration":1.0,"data":{}}]"#
);
// Get inserted event
let res = client
.get("/api/0/buckets/id/events")
.header(ContentType::JSON)
.header(Header::new("Host", "127.0.0.1:5600"))
.dispatch();
assert_eq!(res.status(), rocket::http::Status::Ok);
assert_eq!(
res.into_string().unwrap(),
r#"[{"id":1,"timestamp":"2018-01-01T01:01:01Z","duration":1.0,"data":{}}]"#
);
// Heartbeat
let res = client
.post("/api/0/buckets/id/heartbeat?pulsetime=2")
.header(ContentType::JSON)
.header(Header::new("Host", "127.0.0.1:5600"))
.body(
r#"{
"timestamp": "2018-01-01T01:01:02Z",
"duration": 1.0,
"data": {}
}"#,
)
.dispatch();
assert_eq!(res.status(), rocket::http::Status::Ok);
// After the fix for #559, the heartbeat response includes the DB event ID
assert_eq!(
res.into_string().unwrap(),
r#"{"id":1,"timestamp":"2018-01-01T01:01:01Z","duration":2.0,"data":{}}"#
);
// Get heartbeat event
let res = client
.get("/api/0/buckets/id/events")
.header(ContentType::JSON)
.header(Header::new("Host", "127.0.0.1:5600"))
.dispatch();
assert_eq!(res.status(), rocket::http::Status::Ok);
assert_eq!(
res.into_string().unwrap(),
r#"[{"id":1,"timestamp":"2018-01-01T01:01:01Z","duration":2.0,"data":{}}]"#
);
// Delete event
client
.delete("/api/0/buckets/id/events/1")
.header(Header::new("Host", "127.0.0.1:5600"))
.dispatch();
// Get eventcount
let res = client
.get("/api/0/buckets/id/events/count")
.header(ContentType::JSON)
.header(Header::new("Host", "127.0.0.1:5600"))
.dispatch();
assert_eq!(res.status(), rocket::http::Status::Ok);
assert_eq!(res.into_string().unwrap(), "0");
// Delete bucket
let res = client
.delete("/api/0/buckets/id")
.header(ContentType::JSON)
.header(Header::new("Host", "127.0.0.1:5600"))
.dispatch();
assert_eq!(res.status(), rocket::http::Status::Ok);
}
#[test]
fn test_import_export() {
let server = setup_testserver();
let client = Client::untracked(server).expect("valid instance");
// Import bucket
let res = client
.post("/api/0/import")
.header(ContentType::JSON)
.header(Header::new("Host", "127.0.0.1:5600"))
.body(
r#"{"buckets":
{"id1": {
"id": "id1",
"type": "type",
"client": "client",
"hostname": "hostname",
"events": [{
"timestamp":"2000-01-01T00:00:00Z",
"duration":1.0,
"data": {}
}]
}}}"#,
)
.dispatch();
assert_eq!(res.status(), rocket::http::Status::Ok);
// Import already existing bucket with a new event — should merge instead of fail
let res = client
.post("/api/0/import")
.header(ContentType::JSON)
.header(Header::new("Host", "127.0.0.1:5600"))
.body(
r#"{"buckets":
{"id1": {
"id": "id1",
"type": "type",
"client": "client",
"hostname": "hostname",
"events": [{
"timestamp":"2000-01-02T00:00:00Z",
"duration":1.0,
"data": {}
}]
}}}"#,
)
.dispatch();
assert_eq!(res.status(), rocket::http::Status::Ok);
// Verify events were merged — bucket should now have 2 events
let res = client
.get("/api/0/buckets/id1/events")
.header(ContentType::JSON)
.header(Header::new("Host", "127.0.0.1:5600"))
.dispatch();
assert_eq!(res.status(), rocket::http::Status::Ok);
let events: serde_json::Value = serde_json::from_str(&res.into_string().unwrap()).unwrap();
assert_eq!(events.as_array().unwrap().len(), 2);
// Re-import the first event again — should be idempotent (no duplicate created)
let res = client
.post("/api/0/import")
.header(ContentType::JSON)
.header(Header::new("Host", "127.0.0.1:5600"))
.body(
r#"{"buckets":
{"id1": {
"id": "id1",
"type": "type",
"client": "client",
"hostname": "hostname",
"events": [{
"timestamp":"2000-01-01T00:00:00Z",
"duration":1.0,
"data": {}
}]
}}}"#,
)
.dispatch();
assert_eq!(res.status(), rocket::http::Status::Ok);
// Count should still be 2, not 3 — re-import is idempotent
let res = client
.get("/api/0/buckets/id1/events")
.header(ContentType::JSON)
.header(Header::new("Host", "127.0.0.1:5600"))
.dispatch();
assert_eq!(res.status(), rocket::http::Status::Ok);
let events: serde_json::Value = serde_json::from_str(&res.into_string().unwrap()).unwrap();
assert_eq!(
events.as_array().unwrap().len(),
2,
"Re-importing the same event should be idempotent"
);
// Import a narrower event fully contained within an existing longer event.
// This should be preserved as a distinct event, not dropped by clipped dedup.
let res = client
.post("/api/0/import")
.header(ContentType::JSON)
.header(Header::new("Host", "127.0.0.1:5600"))
.body(
r#"{"buckets":
{"id1": {
"id": "id1",
"type": "type",
"client": "client",
"hostname": "hostname",
"events": [{
"timestamp":"2000-01-01T00:00:30Z",
"duration":30.0,
"data": {}
}]
}}}"#,
)
.dispatch();
assert_eq!(res.status(), rocket::http::Status::Ok);
let res = client
.get("/api/0/buckets/id1/events")
.header(ContentType::JSON)
.header(Header::new("Host", "127.0.0.1:5600"))
.dispatch();
assert_eq!(res.status(), rocket::http::Status::Ok);
let events: serde_json::Value = serde_json::from_str(&res.into_string().unwrap()).unwrap();
assert_eq!(
events.as_array().unwrap().len(),
3,
"Contained event should not be dropped by clipped dedup"
);
// Export single created bucket
let res = client
.get("/api/0/buckets/id1/export")
.header(ContentType::JSON)
.header(Header::new("Host", "127.0.0.1:5600"))
.dispatch();
assert_eq!(res.status(), rocket::http::Status::Ok);
let export: BucketsExport = serde_json::from_str(&res.into_string().unwrap()).unwrap();
// Delete bucket so we can import it again
let res = client
.delete("/api/0/buckets/id1")
.header(ContentType::JSON)
.header(Header::new("Host", "127.0.0.1:5600"))
.dispatch();
assert_eq!(res.status(), rocket::http::Status::Ok);
// Import exported bucket again but with multipart/form-data
let boundary_start = b"--a\r\n";
let disposition = b"Content-Disposition: form-data; name=\"buckets.json\"\r\n";
let content_type = b"Content-Type: application/json\r\n";
let data_start = b"\r\n";
let content = serde_json::to_vec(&export).unwrap();
let boundary_end = b"\r\n--a--";
let sum = [
&boundary_start[..],
&disposition[..],
&content_type[..],
&data_start[..],
&content[..],
&boundary_end[..],
]
.concat();
let res = client
.post("/api/0/import")
.header(Header::new(
"Content-Type",
"multipart/form-data; boundary=a",
))
.header(Header::new("Host", "127.0.0.1:5600"))
.body(&sum[..])
.dispatch();
assert_eq!(res.status(), rocket::http::Status::Ok);
// Get created bucket
let res = client
.get("/api/0/buckets/id1")
.header(ContentType::JSON)
.header(Header::new("Host", "127.0.0.1:5600"))
.dispatch();
assert_eq!(res.status(), rocket::http::Status::Ok);
println!("{:?}", res.into_string());
// Export all buckets
let res = client
.get("/api/0/export")
.header(ContentType::JSON)
.header(Header::new("Host", "127.0.0.1:5600"))
.dispatch();
assert_eq!(res.status(), rocket::http::Status::Ok);
let export: BucketsExport = serde_json::from_str(&res.into_string().unwrap()).unwrap();
let mut buckets = export.buckets;
assert_eq!(buckets.len(), 1);
let b = buckets.remove("id1").unwrap();
assert_eq!(
b.events.unwrap().take_inner().len(),
3,
"Export should preserve the contained event added during merge testing"
);
assert_eq!(buckets.len(), 0);
}
#[test]
fn test_query() {
let server = setup_testserver();
let client = Client::untracked(server).expect("valid instance");
// Minimal query
let res = client
.post("/api/0/query")
.header(ContentType::JSON)
.header(Header::new("Host", "127.0.0.1:5600"))
.body(
r#"{
"timeperiods": ["2000-01-01T00:00:00Z/2020-01-01T00:00:00Z"],
"query": ["return 1;"]
}"#,
)
.dispatch();
assert_eq!(res.status(), rocket::http::Status::Ok);
assert_eq!(res.into_string().unwrap(), r#"[1.0]"#);
// Create bucket to query later
let res = client
.post("/api/0/buckets/id")
.header(ContentType::JSON)
.header(Header::new("Host", "127.0.0.1:5600"))
.body(
r#"{
"id": "id",
"type": "type",
"client": "client",
"hostname": "hostname"
}"#,
)
.dispatch();
assert_eq!(res.status(), rocket::http::Status::Ok);
// Insert a event to query later
let res = client
.post("/api/0/buckets/id/events")
.header(ContentType::JSON)
.header(Header::new("Host", "127.0.0.1:5600"))
.body(
r#"[{
"timestamp": "2018-01-01T01:01:01Z",
"duration": 1.0,
"data": {}
}]"#,
)
.dispatch();
assert_eq!(res.status(), rocket::http::Status::Ok);
// Query events
let res = client
.post("/api/0/query")
.header(ContentType::JSON)
.header(Header::new("Host", "127.0.0.1:5600"))
.body(
r#"{
"timeperiods": ["2000-01-01T00:00:00Z/2020-01-01T00:00:00Z"],
"query": ["return query_bucket(\"id\");"]
}"#,
)
.dispatch();
assert_eq!(res.status(), rocket::http::Status::Ok);
assert_eq!(
res.into_string().unwrap(),
r#"[[{"data":{},"duration":1.0,"id":1,"timestamp":"2018-01-01T01:01:01Z"}]]"#
);
// Test error
let res = client
.post("/api/0/query")
.header(ContentType::JSON)
.header(Header::new("Host", "127.0.0.1:5600"))
.body(
r#"{
"timeperiods": ["2000-01-01T00:00:00Z/2020-01-01T00:00:00Z"],
"query": [""]
}"#,
)
.dispatch();
assert_eq!(res.status(), rocket::http::Status::BadRequest);
assert_eq!(res.into_string().unwrap(), r#"{"message":"EmptyQuery"}"#);
}
fn set_setting_request(client: &Client, key: &str, value: &Value) -> Status {
let body = serde_json::to_string(value).unwrap();
let res = client
.post(format!("/api/0/settings/{}", key))
.header(ContentType::JSON)
.header(Header::new("Host", "127.0.0.1:5600"))
.body(body)
.dispatch();
res.status()
}
#[test]
fn test_illegally_long_key() {
let server = setup_testserver();
let client = Client::untracked(server).expect("valid instance");
// Test getting not found (getting nonexistent key)
let key = "thisisaverylongkthisisaverylongkthisisaverylongkthisisaverylongkthisisaverylongkthisisaverylongkthisisaverylongkthisisaverylongk";
let value = json!("test_value");
let res = set_setting_request(&client, key, &value);
assert_eq!(res, rocket::http::Status::BadRequest);
}
#[test]
fn test_setting_setting() {
let server = setup_testserver();
let client = Client::untracked(server).expect("valid instance");
// Test value creation
let key = "test_key";
let value = json!("test_value");
let response_status = set_setting_request(&client, key, &value);
assert_eq!(response_status, rocket::http::Status::Created);
}
#[test]
fn test_get_unset_setting() {
let server = setup_testserver();
let client = Client::untracked(server).expect("valid instance");
// Test getting not found (getting nonexistent key)
let key = "non_existent_key";
let res = client
.get(format!("/api/0/settings/{}", key))
.header(Header::new("Host", "127.0.0.1:5600"))
.dispatch();
assert_eq!(res.status(), rocket::http::Status::Ok);
assert_eq!(res.into_string().unwrap(), "null")
}
#[test]
fn test_get_settings() {
let server = setup_testserver();
let client = Client::untracked(server).expect("valid instance");
let key1 = "test_key";
let key2 = "test_key_2";
let value = json!("test_value");
let response1_status = set_setting_request(&client, key1, &value);
assert_eq!(response1_status, rocket::http::Status::Created);
let response2_status = set_setting_request(&client, key2, &value);
assert_eq!(response2_status, rocket::http::Status::Created);
let res = client
.get("/api/0/settings")
.header(Header::new("Host", "127.0.0.1:5600"))
.dispatch();
assert_eq!(res.status(), rocket::http::Status::Ok);
let deserialized: Value = serde_json::from_str(&res.into_string().unwrap()).unwrap();
let expected: Value =
serde_json::from_str(r#"{"test_key_2":"test_value","test_key":"test_value"}"#).unwrap();
assert_eq!(deserialized, expected);
}
#[test]
fn test_get_setting() {
let server = setup_testserver();
let client = Client::untracked(server).expect("valid instance");
let key = "test_key";
let value = json!("test_value");
let response_status = set_setting_request(&client, key, &value);
assert_eq!(response_status, rocket::http::Status::Created);
// Test getting
let res = client
.get(format!("/api/0/settings/{}", key))
.header(Header::new("Host", "127.0.0.1:5600"))
.dispatch();
assert_eq!(res.status(), rocket::http::Status::Ok);
let deserialized: Value = serde_json::from_str(&res.into_string().unwrap()).unwrap();
assert_eq!(deserialized, value);
}
#[test]
fn test_get_setting_dotted_key() {
// HTTP accepts dotted keys; JNI getSetting must use the same grammar
// (ActivityWatch/aw-server-rust#653 Greptile: don't reject '.').
let server = setup_testserver();
let client = Client::untracked(server).expect("valid instance");
let key = "nested.like.key";
let value = json!("dotted_value");
assert_eq!(
set_setting_request(&client, key, &value),
rocket::http::Status::Created
);
let res = client
.get(format!("/api/0/settings/{}", key))
.header(Header::new("Host", "127.0.0.1:5600"))
.dispatch();
assert_eq!(res.status(), rocket::http::Status::Ok);
let deserialized: Value = serde_json::from_str(&res.into_string().unwrap()).unwrap();
assert_eq!(deserialized, value);
}
#[test]
fn test_get_setting_list() {
let server = setup_testserver();
let client = Client::untracked(server).expect("valid instance");
// Test array
let key = "test_key_array";
let value = json!([1, 2, 3]);
let response_status = set_setting_request(&client, key, &value);
assert_eq!(response_status, rocket::http::Status::Created);
let res = client
.get(format!("/api/0/settings/{}", key))
.header(Header::new("Host", "127.0.0.1:5600"))
.dispatch();
assert_eq!(res.status(), rocket::http::Status::Ok);
let deserialized: Value = serde_json::from_str(&res.into_string().unwrap()).unwrap();
assert_eq!(deserialized, value);
}
#[test]
fn test_get_setting_dict() {
let server = setup_testserver();
let client = Client::untracked(server).expect("valid instance");
// Test dict
let key = "test_key_dict";
let value = json!({"key": "value", "another_key": "another value"});
let response_status = set_setting_request(&client, key, &value);
assert_eq!(response_status, rocket::http::Status::Created);
let res = client
.get("/api/0/settings/test_key_dict")
.header(Header::new("Host", "127.0.0.1:5600"))
.dispatch();
assert_eq!(res.status(), rocket::http::Status::Ok);
let deserialized: Value = serde_json::from_str(&res.into_string().unwrap()).unwrap();
assert_eq!(deserialized, value);
}
#[test]
fn test_set_setting() {
let server = setup_testserver();
let client = Client::untracked(server).expect("valid instance");
let key = "test_key";
let value1 = json!("test_value");
let value2 = json!("changed_test_value");
let post_1_status = set_setting_request(&client, key, &value1);
assert_eq!(post_1_status, rocket::http::Status::Created);
let res = client
.get(format!("/api/0/settings/{}", key))
.header(Header::new("Host", "127.0.0.1:5600"))
.dispatch();
assert_eq!(res.status(), rocket::http::Status::Ok);
let deserialized: Value = serde_json::from_str(&res.into_string().unwrap()).unwrap();
assert_eq!(deserialized, value1);
let post_2_status = set_setting_request(&client, key, &value2);
assert_eq!(post_2_status, rocket::http::Status::Created);
let res = client
.get("/api/0/settings/test_key")
.header(Header::new("Host", "127.0.0.1:5600"))
.dispatch();
assert_eq!(res.status(), rocket::http::Status::Ok);
let new_deserialized: Value = serde_json::from_str(&res.into_string().unwrap()).unwrap();
assert_eq!(new_deserialized, value2);
}
#[test]
fn test_delete_setting() {
let server = setup_testserver();
let client = Client::untracked(server).expect("valid instance");
let value = json!("test_value");
let response_status = set_setting_request(&client, "test_key", &value);
assert_eq!(response_status, rocket::http::Status::Created);
// Test deleting
let res = client
.delete("/api/0/settings/test_key")
.header(Header::new("Host", "127.0.0.1:5600"))
.dispatch();
assert_eq!(res.status(), rocket::http::Status::Ok);
let res = client
.get("/api/0/settings/test_key")
.header(Header::new("Host", "127.0.0.1:5600"))
.dispatch();
assert_eq!(res.status(), rocket::http::Status::Ok);
assert_eq!(res.into_string().unwrap(), "null");
}
#[test]
fn test_cors_catching() {
let server = setup_testserver();
let client = Client::untracked(server).expect("valid instance");
let res = client
.options("/api/0/buckets/")
.header(ContentType::JSON)
.header(Header::new("Host", "127.0.0.1:5600"))
.dispatch();
assert_eq!(res.status(), rocket::http::Status::Ok);
}
}