Skip to content

Commit 77aaa77

Browse files
committed
test: split composition tests
Signed-off-by: Gustavo Inacio <[email protected]>
1 parent 6365178 commit 77aaa77

File tree

1 file changed

+60
-28
lines changed
  • crates/service/src/middleware

1 file changed

+60
-28
lines changed

crates/service/src/middleware/auth.rs

Lines changed: 60 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ mod tests {
1919
use reqwest::{header, StatusCode};
2020
use sqlx::PgPool;
2121
use tap_core::{manager::Manager, receipt::checks::CheckList};
22+
use tokio::time::sleep;
2223
use tower::{Service, ServiceBuilder, ServiceExt};
2324
use tower_http::auth::AsyncRequireAuthorizationLayer;
2425

@@ -27,80 +28,111 @@ mod tests {
2728
use test_assets::{create_signed_receipt, TAP_EIP712_DOMAIN};
2829

2930
const ALLOCATION_ID: Address = address!("deadbeefcafebabedeadbeefcafebabedeadbeef");
31+
const BEARER_TOKEN: &str = "test";
3032

31-
async fn handle(_: Request<Body>) -> anyhow::Result<Response<Body>> {
32-
Ok(Response::new(Body::default()))
33-
}
34-
35-
#[sqlx::test(migrations = "../../migrations")]
36-
async fn test_middleware_composition(pgpool: PgPool) {
37-
let token = "test".to_string();
33+
async fn service(
34+
pgpool: PgPool,
35+
) -> impl Service<Request<Body>, Response = Response<Body>, Error = impl std::fmt::Debug> {
3836
let context = IndexerTapContext::new(pgpool.clone(), TAP_EIP712_DOMAIN.clone()).await;
3937
let tap_manager = Box::leak(Box::new(Manager::new(
4038
TAP_EIP712_DOMAIN.clone(),
4139
context,
4240
CheckList::empty(),
4341
)));
42+
43+
let registry = prometheus::Registry::new();
4444
let metric = Box::leak(Box::new(
45-
prometheus::register_counter_vec!(
45+
prometheus::register_counter_vec_with_registry!(
4646
"merge_checks_test",
4747
"Failed queries to handler",
48-
&["deployment"]
48+
&["deployment"],
49+
registry,
4950
)
5051
.unwrap(),
5152
));
52-
let free_query = Bearer::new(&token);
53+
let free_query = Bearer::new(BEARER_TOKEN);
5354
let tap_auth = auth::tap_receipt_authorize(tap_manager, metric);
5455
let authorize_requests = free_query.or(tap_auth);
5556

5657
let authorization_middleware = AsyncRequireAuthorizationLayer::new(authorize_requests);
5758

5859
let mut service = ServiceBuilder::new()
5960
.layer(authorization_middleware)
60-
.service_fn(handle);
61+
.service_fn(|_: Request<Body>| async {
62+
Ok::<_, anyhow::Error>(Response::new(Body::default()))
63+
});
6164

62-
let handle = service.ready().await.unwrap();
65+
service.ready().await.unwrap();
66+
service
67+
}
6368

69+
#[sqlx::test(migrations = "../../migrations")]
70+
async fn test_composition_header_valid(pgpool: PgPool) {
71+
let mut service = service(pgpool.clone()).await;
6472
// should allow queries that contains the free token
6573
// if the token does not match, return payment required
6674
let mut req = Request::new(Default::default());
6775
req.headers_mut().insert(
6876
header::AUTHORIZATION,
69-
format!("Bearer {token}").parse().unwrap(),
77+
format!("Bearer {}", BEARER_TOKEN).parse().unwrap(),
7078
);
71-
let res = handle.call(req).await.unwrap();
79+
let res = service.call(req).await.unwrap();
7280
assert_eq!(res.status(), StatusCode::OK);
81+
}
82+
83+
#[sqlx::test(migrations = "../../migrations")]
84+
async fn test_composition_header_invalid(pgpool: PgPool) {
85+
let mut service = service(pgpool.clone()).await;
7386

7487
// if the token exists but is wrong, try the receipt
7588
let mut req = Request::new(Default::default());
7689
req.headers_mut()
7790
.insert(header::AUTHORIZATION, "Bearer wrongtoken".parse().unwrap());
78-
let res = handle.call(req).await.unwrap();
91+
let res = service.call(req).await.unwrap();
7992
// we return the error from tap
8093
assert_eq!(res.status(), StatusCode::PAYMENT_REQUIRED);
94+
}
95+
96+
#[sqlx::test(migrations = "../../migrations")]
97+
async fn test_composition_with_receipt(pgpool: PgPool) {
98+
let mut service = service(pgpool.clone()).await;
8199

82100
let receipt = create_signed_receipt(ALLOCATION_ID, 1, 1, 1).await;
83101

84102
// check with receipt
85103
let mut req = Request::new(Default::default());
86104
req.extensions_mut().insert(receipt);
87-
let res = handle.call(req).await.unwrap();
105+
let res = service.call(req).await.unwrap();
88106
assert_eq!(res.status(), StatusCode::OK);
89107

90-
// todo make this sleep better
91-
tokio::time::sleep(Duration::from_millis(100)).await;
92-
93108
// verify receipts
94-
let result = sqlx::query!("SELECT * FROM scalar_tap_receipts")
95-
.fetch_all(&pgpool)
96-
.await
97-
.unwrap();
98-
assert_eq!(result.len(), 1);
99-
100-
// if it has neither, should return unauthorized
101-
// check no headers
109+
if tokio::time::timeout(Duration::from_secs(1), async {
110+
loop {
111+
let result = sqlx::query!("SELECT * FROM scalar_tap_receipts")
112+
.fetch_all(&pgpool)
113+
.await
114+
.unwrap();
115+
116+
if result.is_empty() {
117+
sleep(Duration::from_millis(50)).await;
118+
} else {
119+
break;
120+
}
121+
}
122+
})
123+
.await
124+
.is_err()
125+
{
126+
panic!("Timeout assertion");
127+
}
128+
}
129+
130+
#[sqlx::test(migrations = "../../migrations")]
131+
async fn test_composition_without_header_or_receipt(pgpool: PgPool) {
132+
let mut service = service(pgpool.clone()).await;
133+
// if it has neither, should return payment required
102134
let req = Request::new(Default::default());
103-
let res = handle.call(req).await.unwrap();
135+
let res = service.call(req).await.unwrap();
104136
assert_eq!(res.status(), StatusCode::PAYMENT_REQUIRED);
105137
}
106138
}

0 commit comments

Comments
 (0)