mirror of
https://github.com/hcengineering/platform.git
synced 2026-09-22 01:25:00 +02:00
implement conditional put/patch
Signed-off-by: Alexander Onnikov <Alexander.Onnikov@xored.com>
This commit is contained in:
@@ -37,3 +37,50 @@ pub async fn get_known() -> eyre::Result<()> {
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[tanu::test]
|
||||
pub async fn get_conditional() -> eyre::Result<()> {
|
||||
let key = random_key();
|
||||
let text = random_text(1024);
|
||||
|
||||
let http = Client::new();
|
||||
|
||||
let res = http.key_put(&key).body(text.clone()).send().await?;
|
||||
check!(res.status().is_success());
|
||||
|
||||
let res = http.key_get(&key).send().await?;
|
||||
check!(res.status().is_success());
|
||||
let etag = res.header("etag").expect("ETag not found");
|
||||
|
||||
// Test without If-None-Match (normal GET)
|
||||
let res = http.key_get(&key).send().await?;
|
||||
check!(res.status().is_success());
|
||||
check_eq!(text, res.text().await?);
|
||||
|
||||
// Test with If-None-Match: *
|
||||
let res = http
|
||||
.key_get(&key)
|
||||
.header("If-None-Match", "*")
|
||||
.send()
|
||||
.await?;
|
||||
check_eq!(res.status(), http::StatusCode::NOT_MODIFIED);
|
||||
|
||||
// Test with correct ETag
|
||||
let res = http
|
||||
.key_get(&key)
|
||||
.header("If-None-Match", etag)
|
||||
.send()
|
||||
.await?;
|
||||
check_eq!(res.status(), http::StatusCode::NOT_MODIFIED);
|
||||
|
||||
// Test with incorrect ETag
|
||||
let res = http
|
||||
.key_get(&key)
|
||||
.header("If-None-Match", "\"invalid-etag\"")
|
||||
.send()
|
||||
.await?;
|
||||
check!(res.status().is_success());
|
||||
check_eq!(text, res.text().await?);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -64,3 +64,48 @@ pub async fn head_known_with_jsonpatch() -> eyre::Result<()> {
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[tanu::test]
|
||||
pub async fn head_conditional() -> eyre::Result<()> {
|
||||
let key = random_key();
|
||||
let text = random_text(1024);
|
||||
|
||||
let http = Client::new();
|
||||
|
||||
let res = http.key_put(&key).body(text.clone()).send().await?;
|
||||
check!(res.status().is_success());
|
||||
|
||||
let res = http.key_head(&key).send().await?;
|
||||
check!(res.status().is_success());
|
||||
let etag = res.header("etag").expect("ETag not found");
|
||||
|
||||
// Test without If-None-Match (normal GET)
|
||||
let res = http.key_head(&key).send().await?;
|
||||
check!(res.status().is_success());
|
||||
|
||||
// Test with If-None-Match: *
|
||||
let res = http
|
||||
.key_head(&key)
|
||||
.header("If-None-Match", "*")
|
||||
.send()
|
||||
.await?;
|
||||
check_eq!(res.status(), http::StatusCode::NOT_MODIFIED);
|
||||
|
||||
// Test with correct ETag
|
||||
let res = http
|
||||
.key_head(&key)
|
||||
.header("If-None-Match", etag)
|
||||
.send()
|
||||
.await?;
|
||||
check_eq!(res.status(), http::StatusCode::NOT_MODIFIED);
|
||||
|
||||
// Test with incorrect ETag
|
||||
let res = http
|
||||
.key_head(&key)
|
||||
.header("If-None-Match", "\"invalid-etag\"")
|
||||
.send()
|
||||
.await?;
|
||||
check!(res.status().is_success());
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
+56
-2
@@ -1,11 +1,11 @@
|
||||
use hulyrs::StatusCode;
|
||||
use serde_json::{self as json, Value, json};
|
||||
use tanu::{check, check_eq, eyre, http::Client};
|
||||
use tanu::{check, check_eq, check_ne, eyre, http::Client};
|
||||
|
||||
use crate::util::*;
|
||||
|
||||
#[tanu::test((10, 10))]
|
||||
pub async fn put_and_patch_contact((initial, patch): (usize, usize)) -> eyre::Result<()> {
|
||||
pub async fn put_and_patch_content((initial, patch): (usize, usize)) -> eyre::Result<()> {
|
||||
let key = random_key();
|
||||
let initial = random_text(1024 * initial);
|
||||
let patch = random_text(1024 * patch);
|
||||
@@ -234,3 +234,57 @@ async fn get_json_patch_safe() -> eyre::Result<()> {
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Eq)]
|
||||
pub enum IfMatch {
|
||||
ETag,
|
||||
Some(&'static str),
|
||||
None,
|
||||
}
|
||||
|
||||
#[tanu::test(1, IfMatch::None, StatusCode::CREATED)]
|
||||
#[tanu::test(2, IfMatch::ETag, StatusCode::CREATED)]
|
||||
#[tanu::test(3, IfMatch::Some("*"), StatusCode::CREATED)]
|
||||
#[tanu::test(4, IfMatch::Some("\"unknown\""), StatusCode::PRECONDITION_FAILED)]
|
||||
pub async fn put_and_patch_conditional(
|
||||
_: usize,
|
||||
if_match: IfMatch,
|
||||
status: StatusCode,
|
||||
) -> eyre::Result<()> {
|
||||
let key = random_key();
|
||||
let initial = random_text(1024);
|
||||
let patch = random_text(1024);
|
||||
|
||||
let http = Client::new();
|
||||
|
||||
// create new blob
|
||||
let res = http.key_put(&key).body(initial.clone()).send().await?;
|
||||
check!(res.status().is_success());
|
||||
|
||||
// check content
|
||||
let res = http.key_get(&key).send().await?;
|
||||
check!(res.status().is_success());
|
||||
let etag = res.header("etag").expect("ETag not found");
|
||||
|
||||
let mut req = http.key_patch(&key).body(patch.clone());
|
||||
|
||||
req = match if_match {
|
||||
IfMatch::ETag => req.header("If-Match", etag),
|
||||
IfMatch::Some(etag) => req.header("If-Match", etag),
|
||||
IfMatch::None => req,
|
||||
};
|
||||
|
||||
let res = req.send().await?;
|
||||
check_eq!(res.status(), status);
|
||||
|
||||
let res = http.key_get(&key).send().await?;
|
||||
check!(res.status().is_success());
|
||||
|
||||
if status.is_success() {
|
||||
check_ne!(res.header("etag"), Some(etag));
|
||||
} else {
|
||||
check_eq!(res.header("etag"), Some(etag));
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -341,3 +341,74 @@ pub async fn put_merge_patch(
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Eq)]
|
||||
pub enum Condition {
|
||||
ETag,
|
||||
IfMatch(&'static str),
|
||||
IfNoneMatch(&'static str),
|
||||
}
|
||||
|
||||
#[tanu::test(1, Condition::ETag, StatusCode::CREATED)]
|
||||
#[tanu::test(2, Condition::IfMatch("*"), StatusCode::PRECONDITION_FAILED)]
|
||||
#[tanu::test(3, Condition::IfNoneMatch("*"), StatusCode::CREATED)]
|
||||
#[tanu::test(4, Condition::IfNoneMatch("\"unknown\""), StatusCode::CREATED)]
|
||||
pub async fn put_conditional_create(
|
||||
_: usize,
|
||||
condition: Condition,
|
||||
status: StatusCode,
|
||||
) -> eyre::Result<()> {
|
||||
let key = random_key();
|
||||
let body = random_text(1024);
|
||||
|
||||
let http = Client::new();
|
||||
|
||||
let mut req = http.key_put(&key).body(body.clone());
|
||||
|
||||
req = match condition {
|
||||
Condition::ETag => req,
|
||||
Condition::IfMatch(etag) => req.header("If-Match", etag),
|
||||
Condition::IfNoneMatch(etag) => req.header("If-None-Match", etag),
|
||||
};
|
||||
|
||||
let res = req.send().await?;
|
||||
check_eq!(res.status(), status);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[tanu::test(1, Condition::ETag, StatusCode::CREATED)]
|
||||
#[tanu::test(2, Condition::IfMatch("*"), StatusCode::CREATED)]
|
||||
#[tanu::test(3, Condition::IfNoneMatch("*"), StatusCode::PRECONDITION_FAILED)]
|
||||
#[tanu::test(
|
||||
4,
|
||||
Condition::IfNoneMatch("\"unknown\""),
|
||||
StatusCode::INTERNAL_SERVER_ERROR
|
||||
)]
|
||||
pub async fn put_conditional_update(
|
||||
_: usize,
|
||||
condition: Condition,
|
||||
status: StatusCode,
|
||||
) -> eyre::Result<()> {
|
||||
let key = random_key();
|
||||
let body = random_text(1024);
|
||||
|
||||
let http = Client::new();
|
||||
|
||||
let res = http.key_put(&key).body(body.clone()).send().await?;
|
||||
check!(res.status().is_success());
|
||||
let etag = res.header("etag").expect("ETag not found");
|
||||
|
||||
let mut req = http.key_put(&key).body(body.clone());
|
||||
|
||||
req = match condition {
|
||||
Condition::ETag => req.header("If-Match", etag),
|
||||
Condition::IfMatch(etag) => req.header("If-Match", etag),
|
||||
Condition::IfNoneMatch(etag) => req.header("If-None-Match", etag),
|
||||
};
|
||||
|
||||
let res = req.send().await?;
|
||||
check_eq!(res.status(), status);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user