257: Accept no content-type as json r=curquiza a=irevoire

closes #253 

Co-authored-by: Tamo <tamo@meilisearch.com>
This commit is contained in:
bors[bot] 2021-06-29 12:54:33 +00:00 committed by GitHub
commit de9ea94f57
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 93 additions and 1 deletions

View File

@ -13,6 +13,7 @@ use crate::Data;
const DEFAULT_RETRIEVE_DOCUMENTS_OFFSET: usize = 0; const DEFAULT_RETRIEVE_DOCUMENTS_OFFSET: usize = 0;
const DEFAULT_RETRIEVE_DOCUMENTS_LIMIT: usize = 20; const DEFAULT_RETRIEVE_DOCUMENTS_LIMIT: usize = 20;
/*
macro_rules! guard_content_type { macro_rules! guard_content_type {
($fn_name:ident, $guard_value:literal) => { ($fn_name:ident, $guard_value:literal) => {
fn $fn_name(head: &actix_web::dev::RequestHead) -> bool { fn $fn_name(head: &actix_web::dev::RequestHead) -> bool {
@ -29,6 +30,19 @@ macro_rules! guard_content_type {
} }
guard_content_type!(guard_json, "application/json"); guard_content_type!(guard_json, "application/json");
*/
fn guard_json(head: &actix_web::dev::RequestHead) -> bool {
if let Some(content_type) = head.headers.get("Content-Type") {
content_type
.to_str()
.map(|v| v.contains("application/json"))
.unwrap_or(false)
} else {
// if no content-type is specified we still accept the data as json!
true
}
}
#[derive(Deserialize)] #[derive(Deserialize)]
struct DocumentParam { struct DocumentParam {
@ -146,6 +160,8 @@ async fn add_documents(
Ok(HttpResponse::Accepted().json(serde_json::json!({ "updateId": update_status.id() }))) Ok(HttpResponse::Accepted().json(serde_json::json!({ "updateId": update_status.id() })))
} }
/// Route used when the payload type is "application/json"
/// Used to add or replace documents
async fn update_documents( async fn update_documents(
data: GuardedData<Private, Data>, data: GuardedData<Private, Data>,
path: web::Path<IndexParam>, path: web::Path<IndexParam>,

View File

@ -1,7 +1,83 @@
use crate::common::{GetAllDocumentsOptions, Server};
use actix_web::test;
use chrono::DateTime; use chrono::DateTime;
use meilisearch_http::create_app;
use serde_json::{json, Value}; use serde_json::{json, Value};
use crate::common::{GetAllDocumentsOptions, Server}; /// This is the basic usage of our API and every other tests uses the content-type application/json
#[actix_rt::test]
async fn add_documents_test_json_content_types() {
let document = json!([
{
"id": 1,
"content": "Bouvier Bernois",
}
]);
// this is a what is expected and should work
let server = Server::new().await;
let app = test::init_service(create_app!(&server.service.0, true)).await;
let req = test::TestRequest::post()
.uri("/indexes/dog/documents")
.set_payload(document.to_string())
.insert_header(("content-type", "application/json"))
.to_request();
let res = test::call_service(&app, req).await;
let status_code = res.status();
let body = test::read_body(res).await;
let response: Value = serde_json::from_slice(&body).unwrap_or_default();
assert_eq!(status_code, 202);
assert_eq!(response, json!({ "updateId": 0 }));
}
/// no content type is still supposed to be accepted as json
#[actix_rt::test]
async fn add_documents_test_no_content_types() {
let document = json!([
{
"id": 1,
"content": "Montagne des Pyrénées",
}
]);
let server = Server::new().await;
let app = test::init_service(create_app!(&server.service.0, true)).await;
let req = test::TestRequest::post()
.uri("/indexes/dog/documents")
.set_payload(document.to_string())
.insert_header(("content-type", "application/json"))
.to_request();
let res = test::call_service(&app, req).await;
let status_code = res.status();
let body = test::read_body(res).await;
let response: Value = serde_json::from_slice(&body).unwrap_or_default();
assert_eq!(status_code, 202);
assert_eq!(response, json!({ "updateId": 0 }));
}
/// any other content-type is must be refused
#[actix_rt::test]
async fn add_documents_test_bad_content_types() {
let document = json!([
{
"id": 1,
"content": "Leonberg",
}
]);
let server = Server::new().await;
let app = test::init_service(create_app!(&server.service.0, true)).await;
let req = test::TestRequest::post()
.uri("/indexes/dog/documents")
.set_payload(document.to_string())
.insert_header(("content-type", "text/plain"))
.to_request();
let res = test::call_service(&app, req).await;
let status_code = res.status();
let body = test::read_body(res).await;
assert_eq!(status_code, 405);
assert!(body.is_empty());
}
#[actix_rt::test] #[actix_rt::test]
async fn add_documents_no_index_creation() { async fn add_documents_no_index_creation() {