|
1 | 1 | use crate::db::{
|
2 |
| - accounting::{get_all_accountings_for_channel, Side}, |
| 2 | + accounting::{get_all_accountings_for_channel, update_accounting, Side}, |
3 | 3 | event_aggregate::{latest_approve_state_v5, latest_heartbeats, latest_new_state_v5},
|
4 | 4 | insert_channel, insert_validator_messages, list_channels,
|
5 | 5 | spendable::{fetch_spendable, get_all_spendables_for_channel, update_spendable},
|
@@ -310,6 +310,38 @@ pub async fn get_all_spender_limits<C: Locked + 'static>(
|
310 | 310 | Ok(success_response(serde_json::to_string(&res)?))
|
311 | 311 | }
|
312 | 312 |
|
| 313 | +/// internally, to make the validator worker to add a spender leaf in NewState we'll just update Accounting |
| 314 | +pub async fn add_spender_leaf<C: Locked + 'static>( |
| 315 | + req: Request<Body>, |
| 316 | + app: &Application<C>, |
| 317 | +) -> Result<Response<Body>, ResponseError> { |
| 318 | + let route_params = req |
| 319 | + .extensions() |
| 320 | + .get::<RouteParams>() |
| 321 | + .expect("request should have route params"); |
| 322 | + let spender = Address::from_str(&route_params.index(1))?; |
| 323 | + |
| 324 | + let channel = req |
| 325 | + .extensions() |
| 326 | + .get::<Channel>() |
| 327 | + .expect("Request should have Channel") |
| 328 | + .to_owned(); |
| 329 | + |
| 330 | + update_accounting( |
| 331 | + app.pool.clone(), |
| 332 | + channel.id(), |
| 333 | + spender, |
| 334 | + Side::Spender, |
| 335 | + UnifiedNum::from_u64(0), |
| 336 | + ) |
| 337 | + .await?; |
| 338 | + |
| 339 | + // TODO: Replace with SpenderResponse |
| 340 | + Ok(success_response(serde_json::to_string(&SuccessResponse { |
| 341 | + success: true, |
| 342 | + })?)) |
| 343 | +} |
| 344 | + |
313 | 345 | async fn get_corresponding_new_state(
|
314 | 346 | pool: &DbPool,
|
315 | 347 | logger: &Logger,
|
@@ -388,6 +420,7 @@ mod test {
|
388 | 420 | use adapter::primitives::Deposit;
|
389 | 421 | use hyper::StatusCode;
|
390 | 422 | use primitives::{
|
| 423 | + test_util::{ADVERTISER, CREATOR, GUARDIAN, PUBLISHER}, |
391 | 424 | util::tests::prep_db::{ADDRESSES, DUMMY_CAMPAIGN, IDS},
|
392 | 425 | BigNum,
|
393 | 426 | };
|
@@ -596,4 +629,86 @@ mod test {
|
596 | 629 | assert_eq!(expected, res.expect_err("Should return an error"));
|
597 | 630 | }
|
598 | 631 | }
|
| 632 | + |
| 633 | + #[tokio::test] |
| 634 | + async fn adds_and_retrieves_spender_leaf() { |
| 635 | + let app = setup_dummy_app().await; |
| 636 | + let channel = DUMMY_CAMPAIGN.channel; |
| 637 | + |
| 638 | + insert_channel(&app.pool, channel) |
| 639 | + .await |
| 640 | + .expect("should insert channel"); |
| 641 | + |
| 642 | + let get_accounting_request = |channel: Channel| { |
| 643 | + Request::builder() |
| 644 | + .extension(channel) |
| 645 | + .body(Body::empty()) |
| 646 | + .expect("Should build Request") |
| 647 | + }; |
| 648 | + let add_spender_request = |channel: Channel| { |
| 649 | + let param = RouteParams(vec![channel.id().to_string(), CREATOR.to_string()]); |
| 650 | + Request::builder() |
| 651 | + .extension(channel) |
| 652 | + .extension(param) |
| 653 | + .body(Body::empty()) |
| 654 | + .expect("Should build Request") |
| 655 | + }; |
| 656 | + |
| 657 | + // Calling with non existent accounting |
| 658 | + let res = add_spender_leaf(add_spender_request(channel), &app) |
| 659 | + .await |
| 660 | + .expect("Should add"); |
| 661 | + assert_eq!(StatusCode::OK, res.status()); |
| 662 | + |
| 663 | + let res = get_accounting_for_channel(get_accounting_request(channel), &app) |
| 664 | + .await |
| 665 | + .expect("should get response"); |
| 666 | + assert_eq!(StatusCode::OK, res.status()); |
| 667 | + |
| 668 | + let accounting_response = res_to_accounting_response(res).await; |
| 669 | + |
| 670 | + // Making sure a new entry has been created |
| 671 | + assert_eq!( |
| 672 | + accounting_response.balances.spenders.get(&CREATOR), |
| 673 | + Some(&UnifiedNum::from_u64(0)), |
| 674 | + ); |
| 675 | + |
| 676 | + let mut balances = Balances::<CheckedState>::new(); |
| 677 | + balances |
| 678 | + .spend(*CREATOR, *PUBLISHER, UnifiedNum::from_u64(200)) |
| 679 | + .expect("should not overflow"); |
| 680 | + balances |
| 681 | + .spend(*ADVERTISER, *GUARDIAN, UnifiedNum::from_u64(100)) |
| 682 | + .expect("Should not overflow"); |
| 683 | + spend_amount(app.pool.clone(), channel.id(), balances.clone()) |
| 684 | + .await |
| 685 | + .expect("should spend"); |
| 686 | + |
| 687 | + let res = get_accounting_for_channel(get_accounting_request(channel), &app) |
| 688 | + .await |
| 689 | + .expect("should get response"); |
| 690 | + assert_eq!(StatusCode::OK, res.status()); |
| 691 | + |
| 692 | + let accounting_response = res_to_accounting_response(res).await; |
| 693 | + |
| 694 | + assert_eq!(balances, accounting_response.balances); |
| 695 | + |
| 696 | + let res = add_spender_leaf(add_spender_request(channel), &app) |
| 697 | + .await |
| 698 | + .expect("Should add"); |
| 699 | + assert_eq!(StatusCode::OK, res.status()); |
| 700 | + |
| 701 | + let res = get_accounting_for_channel(get_accounting_request(channel), &app) |
| 702 | + .await |
| 703 | + .expect("should get response"); |
| 704 | + assert_eq!(StatusCode::OK, res.status()); |
| 705 | + |
| 706 | + let accounting_response = res_to_accounting_response(res).await; |
| 707 | + |
| 708 | + // Balances shouldn't change |
| 709 | + assert_eq!( |
| 710 | + accounting_response.balances.spenders.get(&CREATOR), |
| 711 | + balances.spenders.get(&CREATOR), |
| 712 | + ); |
| 713 | + } |
599 | 714 | }
|
0 commit comments