From 17d73bb73f4396c22ca24c3839a5449f5e28b4e5 Mon Sep 17 00:00:00 2001 From: Yigit Sever Date: Tue, 13 Apr 2021 04:05:44 +0300 Subject: Housekeeping Moved tests out of routes.rs into their own file Learned how to use lib.rs, now we have cargo doc support as well --- src/routes.rs | 380 +--------------------------------------------------------- 1 file changed, 3 insertions(+), 377 deletions(-) (limited to 'src/routes.rs') diff --git a/src/routes.rs b/src/routes.rs index ed2acad..e4bdee4 100644 --- a/src/routes.rs +++ b/src/routes.rs @@ -1,10 +1,11 @@ -use gradecoin::schema::Db; +/// Endpoints and their construction use warp::{Filter, Rejection, Reply}; use crate::custom_filters; use crate::handlers; +use crate::schema::Db; -/// Root, all routes combined +/// Every route combined pub fn consensus_routes(db: Db) -> impl Filter + Clone { transaction_list(db.clone()) .or(register_user(db.clone())) @@ -38,15 +39,6 @@ pub fn block_list(db: Db) -> impl Filter impl Filter + Clone { - warp::path!("transaction") - .and(warp::post()) - .and(custom_filters::transaction_json_body()) - .and(custom_filters::with_db(db)) - .and_then(handlers::propose_transaction) -} - /// POST /transaction warp route pub fn auth_transaction_propose( db: Db, @@ -68,369 +60,3 @@ pub fn block_propose(db: Db) -> impl Filter Db { - let db = create_database(); - - db.users.write().insert( - "mock_transaction_source".to_owned(), - User { - user_id: MetuId::new("e254275".to_owned()).unwrap(), - public_key: -"-----BEGIN PUBLIC KEY----- -MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4nU0G4WjkmcQUx0hq6LQ -uV5Q+ACmUFL/OjoYMDwC/O/6pCd1UZgCfgHN2xEffDPznzcTn8OiFRxr4oWyBiny -rUpnY4mhy0SQUwoeCw7YkcHAyhCjNT74aR/ohX0MCj0qRRdbt5ZQXM/GC3HJuXE1 -ptSuhFgQxziItamn8maoJ6JUSVEXVO1NOrrjoM3r7Q+BK2B+sX4/bLZ+VG5g1q2n -EbFdTHS6pHqtZNHQndTmEKwRfh0RYtzEzOXuO6e1gQY42Tujkof40dhGCIU7TeIG -GHwdFxy1niLkXwtHNjV7lnIOkTbx6+sSPamRfQAlZqUWM2Lf5o+7h3qWP3ENB138 -sQIDAQAB ------END PUBLIC KEY-----" - .to_owned(), - balance: 0, - }, - ); - db.pending_transactions.write().insert( - "hash_value".to_owned(), - Transaction { - by: "source_account".to_owned(), - source: "source_account".to_owned(), - target: "target_account".to_owned(), - amount: 20, - timestamp: chrono::NaiveDate::from_ymd(2021, 04, 09).and_hms(1, 30, 30), - }, - ); - - *db.blockchain.write() = Block { - transaction_list: vec![ - "old_transaction_hash_1".to_owned(), - "old_transaction_hash_2".to_owned(), - "old_transaction_hash_3".to_owned(), - ], - nonce: 0, - timestamp: chrono::NaiveDate::from_ymd(2021, 04, 08).and_hms(12, 30, 30), - hash: "not_a_thing_yet".to_owned(), - }; - - db - } - - fn mocked_jwt() -> String { - - let claims = Claims { - tha: "6692e774eba7fb92dc0fe6cf7347591e".to_owned(), - iat: 1516239022, - }; - let header = Header::new(Algorithm::RS256); - encode(&header, &claims, &EncodingKey::from_rsa_pem(private_key_pem.as_bytes()).unwrap()).unwrap() - } - /// Create a mock user that is allowed to be in gradecoin to be used in tests - fn priviliged_mocked_user() -> AuthRequest { - AuthRequest { - student_id: String::from("e254275"), - public_key: "NOT IMPLEMENTED".to_owned(), - } - } - - /// Create a mock user that is NOT allowed to be in gradecoin to be used in tests - fn unpriviliged_mocked_user() -> AuthRequest { - AuthRequest { - student_id: String::from("foobarbaz"), - public_key: "NOT IMPLEMENTED".to_owned(), - } - } - - /// Create a mock transaction to be used in tests - fn mocked_transaction() -> Transaction { - Transaction { - by: "mock_transaction_source".to_owned(), - source: "mock_transaction_source".to_owned(), - target: "mock_transaction_target".to_owned(), - amount: 25, - timestamp: chrono::NaiveDate::from_ymd(2021, 04, 09).and_hms(14, 30, 00), - } - } - - /// Create a mock block with a correct mined hash to be used in tests - fn mocked_block() -> Block { - Block { - transaction_list: vec!["hash_value".to_owned()], - nonce: 3831993, - timestamp: chrono::NaiveDate::from_ymd(2021, 04, 08).and_hms(12, 30, 30), - hash: "2b648ffab5d9af1d5d5fc052fc9e51b882fc4fb0c998608c99232f9282000000".to_owned(), - } - } - - /// Create a mock block with a wrong hash and nonce - fn mocked_wrong_block() -> Block { - Block { - transaction_list: vec!["foobarbaz".to_owned(), "dazsaz".to_owned()], - nonce: 1000, // can you imagine - timestamp: chrono::NaiveDate::from_ymd(2021, 04, 12).and_hms(05, 29, 30), - hash: "tnarstnarsuthnarsthlarjstk".to_owned(), - } - } - - /// Test simple GET request to /transaction, resource that exists - /// https://tools.ietf.org/html/rfc7231#section-6.3.1 - /// We should get the only pending transaction available in the database as json - #[tokio::test] - async fn get_pending_transactions() { - let db = mocked_db(); - - let reply = consensus_routes(db); - - let res = warp::test::request() - .method("GET") - .path("/transaction") - .reply(&reply) - .await; - - assert_eq!(res.status(), StatusCode::OK); - - let expected_json_body = r#"[{"by":"source_account","source":"source_account","target":"target_account","amount":20,"timestamp":"2021-04-09T01:30:30"}]"#; - - assert_eq!(res.body(), expected_json_body); - } - - /// Test simple GET request to /block, resource that exists - /// https://tools.ietf.org/html/rfc7231#section-6.3.1 - /// Should return the single block available in the database as json - #[tokio::test] - async fn get_blockchain() { - let db = mocked_db(); - let filter = consensus_routes(db); - - let res = warp::test::request() - .method("GET") - .path("/block") - .reply(&filter) - .await; - - assert_eq!(res.status(), StatusCode::OK); - - let expected_json_body = r#"{"transaction_list":["old_transaction_hash_1","old_transaction_hash_2","old_transaction_hash_3"],"nonce":0,"timestamp":"2021-04-08T12:30:30","hash":"not_a_thing_yet"}"#; - assert_eq!(res.body(), expected_json_body); - } - - /// Test a simple GET request to a nonexisting path - /// https://tools.ietf.org/html/rfc7231#section-6.5.4 - /// Should respond with 404 and stop - #[tokio::test] - async fn get_nonexisting_path_404() { - let db = mocked_db(); - let filter = consensus_routes(db); - - let res = warp::test::request() - .method("GET") - .path("/this_path_does_not_exist") - .reply(&filter) - .await; - - assert_eq!(res.status(), StatusCode::NOT_FOUND); - } - - /// Test a POST request to /transaction, a resource that exists - /// https://tools.ietf.org/html/rfc7231#section-6.3.2 - /// Should accept the json request, create - /// the transaction and add it to pending transactions in the db - #[tokio::test] - async fn post_json_201() { - let db = mocked_db(); - let filter = consensus_routes(db.clone()); - let res = warp::test::request() - .method("POST") - .json(&mocked_transaction()) - .path("/transaction") - .reply(&filter) - .await; - - assert_eq!(res.status(), StatusCode::CREATED); - assert_eq!(db.pending_transactions.read().len(), 2); - } - - /// Test a POST request to /transaction, a resource that exists - /// https://tools.ietf.org/html/rfc7231#section-6.3.2 - /// Should accept the json request, create - /// the transaction and add it to pending transactions in the db - #[tokio::test] - async fn post_auth_json_201() { - let db = mocked_db(); - let filter = consensus_routes(db.clone()); - - let res = warp::test::request() - .method("POST") - .json(&mocked_transaction()) - .header("Authorization", format!("Bearer {}", &mocked_jwt())) - .path("/transaction") - .reply(&filter) - .await; - - assert_eq!(res.status(), StatusCode::CREATED); - assert_eq!(db.pending_transactions.read().len(), 2); - } - - /// Test a POST request to /transaction, a resource that exists - /// https://tools.ietf.org/html/rfc7231#section-6.3.2 - /// Should accept the json request, create - /// the transaction and add it to pending transactions in the db - #[tokio::test] - async fn post_auth_json_400() { - let db = mocked_db(); - let filter = consensus_routes(db.clone()); - - let res = warp::test::request() - .method("POST") - .json(&mocked_transaction()) - .header("Authorization", "Bearer aaaaaaaasdlkjaldkasljdaskjlaaaaaaaaaaaaaa") - .path("/transaction") - .reply(&filter) - .await; - - assert_eq!(res.status(), StatusCode::BAD_REQUEST); - assert_eq!(db.pending_transactions.read().len(), 1); - } - - /// Test a POST request to /block, a resource that exists - /// https://tools.ietf.org/html/rfc7231#section-6.3.2 - /// Should accept the json request, create - /// the block - #[tokio::test] - async fn post_block_201() { - let db = mocked_db(); - let filter = consensus_routes(db.clone()); - - let res = warp::test::request() - .method("POST") - .json(&mocked_block()) - .path("/block") - .reply(&filter) - .await; - - assert_eq!(res.status(), StatusCode::CREATED); - assert_eq!( - *db.blockchain.read().hash, - "2b648ffab5d9af1d5d5fc052fc9e51b882fc4fb0c998608c99232f9282000000".to_owned() - ); - } - - /// Test a POST request to /block, a resource that exists - /// https://tools.ietf.org/html/rfc7231#section-6.3.2 - /// Should reject the block because of the wrong hash - #[tokio::test] - async fn post_block_wrong_hash() { - let db = mocked_db(); - let filter = consensus_routes(db.clone()); - - let res = warp::test::request() - .method("POST") - .json(&mocked_wrong_block()) - .path("/block") - .reply(&filter) - .await; - - assert_eq!(res.status(), StatusCode::BAD_REQUEST); - } - - /// Test a POST request to /register, an endpoint that exists - /// https://tools.ietf.org/html/rfc7231#section-6.3.2 - /// Should accept the json request, create a new user and - /// add it to the user hashmap in the db - #[tokio::test] - async fn post_register_priviliged_user() { - let db = mocked_db(); - let filter = consensus_routes(db.clone()); - - let res = warp::test::request() - .method("POST") - .json(&priviliged_mocked_user()) - .path("/register") - .reply(&filter) - .await; - - println!("{:?}", res.body()); - assert_eq!(res.status(), StatusCode::CREATED); - assert_eq!(db.users.read().len(), 2); - } - - /// Test a POST request to /transaction, an endpoint that exists - /// https://tools.ietf.org/html/rfc7231#section-6.3.2 - /// Should NOT accept the json request as the user is unpriviliged - #[tokio::test] - async fn post_register_unpriviliged_user() { - let db = mocked_db(); - let filter = consensus_routes(db.clone()); - - let res = warp::test::request() - .method("POST") - .json(&unpriviliged_mocked_user()) - .path("/register") - .reply(&filter) - .await; - - println!("{:?}", res.body()); - assert_eq!(res.status(), StatusCode::BAD_REQUEST); - assert_eq!(db.users.read().len(), 1); - } - - /// Test a POST request to /transaction, a resource that exists with a longer than expected - /// payload - /// https://tools.ietf.org/html/rfc7231#section-6.5.11 - /// Should return 413 to user - #[tokio::test] - async fn post_too_long_content_413() { - let db = mocked_db(); - let filter = consensus_routes(db); - - let res = warp::test::request() - .method("POST") - .header("content-length", 1024 * 36) - .path("/transaction") - .reply(&filter) - .await; - - assert_eq!(res.status(), StatusCode::PAYLOAD_TOO_LARGE); - } -} - -// TODO: POST block without correct transactions test <09-04-21, yigit> // -// TODO: POST transaction while that source has pending transaction test <09-04-21, yigit> // -- cgit v1.2.3-70-g09d2