1
0
mirror of https://github.com/fafhrd91/actix-web synced 2024-11-23 16:21:06 +01:00

fix resource match with params #841

This commit is contained in:
Nikolay Kim 2019-05-15 10:31:40 -07:00
parent 80f4ef9aac
commit e1ff3bf8fa
8 changed files with 77 additions and 18 deletions

View File

@ -1,5 +1,7 @@
# Changes
## [1.0.0-rc.1] - 2019-05-xx
### Add
* `QueryConfig`, similar to `JsonConfig` for customizing error handling of query extractors.
@ -8,6 +10,11 @@
* `JsonConfig` is now `Send + Sync`, this implies that `error_handler` must be `Send + Sync` too.
### Fixed
* Codegen with parameters in the path only resolves the first registered endpoint #841
## [1.0.0-beta.4] - 2019-05-12
### Add

View File

@ -68,7 +68,7 @@ rust-tls = ["rustls", "actix-server/rust-tls"]
actix-codec = "0.1.2"
actix-service = "0.4.0"
actix-utils = "0.4.0"
actix-router = "0.1.3"
actix-router = "0.1.5"
actix-rt = "0.2.2"
actix-web-codegen = "0.1.0-beta.1"
actix-http = { version = "0.2.0", features=["fail"] }

View File

@ -18,7 +18,7 @@ name = "actix_web_actors"
path = "src/lib.rs"
[dependencies]
actix = "0.8.0"
actix = "0.8.2"
actix-web = "1.0.0-beta.5"
actix-http = "0.2.0"
actix-codec = "0.1.2"

View File

@ -1,6 +1,6 @@
[package]
name = "actix-web-codegen"
version = "0.1.0-beta.1"
version = "0.1.0"
description = "Actix web proc macros"
readme = "README.md"
authors = ["Nikolay Kim <fafhrd91@gmail.com>"]

View File

@ -1,7 +1,7 @@
use actix_http::HttpService;
use actix_http_test::TestServer;
use actix_web::{http, App, HttpResponse, Responder, web::{Path}};
use actix_web_codegen::{get, post, put, delete};
use actix_web::{http, web::Path, App, HttpResponse, Responder};
use actix_web_codegen::{delete, get, post, put};
use futures::{future, Future};
#[get("/test")]

View File

@ -104,7 +104,9 @@ pub enum QueryPayloadError {
impl ResponseError for QueryPayloadError {
fn error_response(&self) -> HttpResponse {
match *self {
QueryPayloadError::Deserialize(_) => HttpResponse::new(StatusCode::BAD_REQUEST),
QueryPayloadError::Deserialize(_) => {
HttpResponse::new(StatusCode::BAD_REQUEST)
}
}
}
}
@ -163,7 +165,10 @@ mod tests {
#[test]
fn test_query_payload_error() {
let resp: HttpResponse = QueryPayloadError::Deserialize(serde_urlencoded::from_str::<i32>("bad query").unwrap_err()).error_response();
let resp: HttpResponse = QueryPayloadError::Deserialize(
serde_urlencoded::from_str::<i32>("bad query").unwrap_err(),
)
.error_response();
assert_eq!(resp.status(), StatusCode::BAD_REQUEST);
}

View File

@ -606,7 +606,7 @@ mod tests {
use crate::http::{header, HeaderValue, Method, StatusCode};
use crate::service::{ServiceRequest, ServiceResponse};
use crate::test::{call_service, init_service, TestRequest};
use crate::{web, App, Error, HttpResponse};
use crate::{guard, web, App, Error, HttpResponse};
fn md<S, B>(
req: ServiceRequest,
@ -723,4 +723,45 @@ mod tests {
let resp = call_service(&mut srv, req);
assert_eq!(resp.status(), StatusCode::BAD_REQUEST);
}
#[test]
fn test_resource_guards() {
let mut srv = init_service(
App::new()
.service(
web::resource("/test/{p}")
.guard(guard::Get())
.to(|| HttpResponse::Ok()),
)
.service(
web::resource("/test/{p}")
.guard(guard::Put())
.to(|| HttpResponse::Created()),
)
.service(
web::resource("/test/{p}")
.guard(guard::Delete())
.to(|| HttpResponse::NoContent()),
),
);
let req = TestRequest::with_uri("/test/it")
.method(Method::GET)
.to_request();
let resp = call_service(&mut srv, req);
assert_eq!(resp.status(), StatusCode::OK);
let req = TestRequest::with_uri("/test/it")
.method(Method::PUT)
.to_request();
let resp = call_service(&mut srv, req);
assert_eq!(resp.status(), StatusCode::CREATED);
let req = TestRequest::with_uri("/test/it")
.method(Method::DELETE)
.to_request();
let resp = call_service(&mut srv, req);
assert_eq!(resp.status(), StatusCode::NO_CONTENT);
}
}

View File

@ -8,9 +8,9 @@ use serde::de;
use serde_urlencoded;
use crate::dev::Payload;
use crate::error::QueryPayloadError;
use crate::extract::FromRequest;
use crate::request::HttpRequest;
use crate::error::QueryPayloadError;
#[derive(PartialEq, Eq, PartialOrd, Ord)]
/// Extract typed information from from the request's query.
@ -188,8 +188,8 @@ pub struct QueryConfig {
impl QueryConfig {
/// Set custom error handler
pub fn error_handler<F>(mut self, f: F) -> Self
where
F: Fn(QueryPayloadError, &HttpRequest) -> Error + Send + Sync + 'static,
where
F: Fn(QueryPayloadError, &HttpRequest) -> Error + Send + Sync + 'static,
{
self.ehandler = Some(Arc::new(f));
self
@ -198,21 +198,19 @@ impl QueryConfig {
impl Default for QueryConfig {
fn default() -> Self {
QueryConfig {
ehandler: None,
}
QueryConfig { ehandler: None }
}
}
#[cfg(test)]
mod tests {
use actix_http::http::StatusCode;
use derive_more::Display;
use serde_derive::Deserialize;
use actix_http::http::StatusCode;
use super::*;
use crate::test::TestRequest;
use crate::error::InternalError;
use crate::test::TestRequest;
use crate::HttpResponse;
#[derive(Deserialize, Debug, Display)]
@ -244,12 +242,20 @@ mod tests {
.data(QueryConfig::default().error_handler(|e, _| {
let resp = HttpResponse::UnprocessableEntity().finish();
InternalError::from_response(e, resp).into()
})).to_srv_request();
}))
.to_srv_request();
let (req, mut pl) = req.into_parts();
let query = Query::<Id>::from_request(&req, &mut pl);
assert!(query.is_err());
assert_eq!(query.unwrap_err().as_response_error().error_response().status(), StatusCode::UNPROCESSABLE_ENTITY);
assert_eq!(
query
.unwrap_err()
.as_response_error()
.error_response()
.status(),
StatusCode::UNPROCESSABLE_ENTITY
);
}
}