Skip to content

Commit 52885a4

Browse files
committed
sentry - routes - campaign close - axum & tests
1 parent 0628fec commit 52885a4

File tree

1 file changed

+54
-27
lines changed

1 file changed

+54
-27
lines changed

sentry/src/routes/campaign.rs

Lines changed: 54 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -450,6 +450,41 @@ pub async fn campaign_list<C: Locked + 'static>(
450450
Ok(success_response(serde_json::to_string(&list_response)?))
451451
}
452452

453+
/// POST `/v5/campaign/:id/close` (auth required)
454+
///
455+
/// **Can only be called by the [`Campaign.creator`]!**
456+
/// To close a campaign, just set it's budget to what it's spent so far (so that remaining == 0)
457+
/// newBudget = totalSpent, i.e. newBudget = oldBudget - remaining
458+
pub async fn close_campaign_axum<C: Locked + 'static>(
459+
Extension(app): Extension<Arc<Application<C>>>,
460+
Extension(auth): Extension<Auth>,
461+
Extension(campaign_context): Extension<ChainOf<Campaign>>,
462+
) -> Result<Json<SuccessResponse>, ResponseError> {
463+
let mut campaign = campaign_context.context;
464+
465+
if auth.uid.to_address() != campaign.creator {
466+
Err(ResponseError::Forbidden(
467+
"Request not sent by campaign creator".to_string(),
468+
))
469+
} else {
470+
let old_remaining = app
471+
.campaign_remaining
472+
.getset_remaining_to_zero(campaign.id)
473+
.await
474+
.map_err(|e| ResponseError::BadRequest(e.to_string()))?;
475+
476+
campaign.budget = campaign
477+
.budget
478+
.checked_sub(&UnifiedNum::from(old_remaining))
479+
.ok_or_else(|| {
480+
ResponseError::BadRequest("Campaign budget overflow/underflow".to_string())
481+
})?;
482+
update_campaign(&app.pool, &campaign).await?;
483+
484+
Ok(Json(SuccessResponse { success: true }))
485+
}
486+
}
487+
453488
/// POST `/v5/campaign/:id/close` (auth required)
454489
///
455490
/// **Can only be called by the [`Campaign.creator`]!**
@@ -1313,7 +1348,6 @@ mod test {
13131348
.expect("Should create campaign")
13141349
.0;
13151350

1316-
13171351
assert_ne!(DUMMY_CAMPAIGN.id, create_response.id);
13181352

13191353
let campaign_remaining = CampaignRemaining::new(app.redis.clone());
@@ -1378,7 +1412,8 @@ mod test {
13781412

13791413
create_campaign_axum(Json(create_second), auth.clone(), app.clone())
13801414
.await
1381-
.expect("Should create campaign").0
1415+
.expect("Should create campaign")
1416+
.0
13821417
};
13831418

13841419
// No budget left for new campaigns
@@ -1554,12 +1589,15 @@ mod test {
15541589
let campaign =
15551590
CreateCampaign::from_campaign_erased(DUMMY_CAMPAIGN.clone(), None).into_campaign();
15561591

1557-
let app = setup_dummy_app().await;
1592+
let app_guard = setup_dummy_app().await;
15581593

1559-
let channel_chain = app
1594+
let channel_chain = app_guard
15601595
.config
15611596
.find_chain_of(DUMMY_CAMPAIGN.channel.token)
15621597
.expect("Channel token should be whitelisted in config!");
1598+
1599+
let app = Extension(Arc::new(app_guard.app.clone()));
1600+
15631601
let channel_context = channel_chain.with_channel(DUMMY_CAMPAIGN.channel);
15641602

15651603
insert_channel(&app.pool, &channel_context)
@@ -1569,11 +1607,12 @@ mod test {
15691607
.await
15701608
.expect("Should insert dummy campaign");
15711609

1572-
let campaign_context = app
1573-
.config
1574-
.find_chain_of(campaign.channel.token)
1575-
.expect("Config should have the Dummy campaign.channel.token")
1576-
.with(campaign.clone());
1610+
let campaign_context = Extension(
1611+
app.config
1612+
.find_chain_of(campaign.channel.token)
1613+
.expect("Config should have the Dummy campaign.channel.token")
1614+
.with(campaign.clone()),
1615+
);
15771616

15781617
// Test if remaining is set to 0
15791618
{
@@ -1582,19 +1621,13 @@ mod test {
15821621
.await
15831622
.expect("should set");
15841623

1585-
let auth = Auth {
1624+
let auth = Extension(Auth {
15861625
era: 0,
15871626
uid: ValidatorId::from(campaign.creator),
15881627
chain: campaign_context.chain.clone(),
1589-
};
1628+
});
15901629

1591-
let req = Request::builder()
1592-
.extension(auth)
1593-
.extension(campaign_context.clone())
1594-
.body(Body::empty())
1595-
.expect("Should build Request");
1596-
1597-
close_campaign(req, &app)
1630+
close_campaign_axum(app.clone(), auth.clone(), campaign_context.clone())
15981631
.await
15991632
.expect("Should close campaign");
16001633

@@ -1618,19 +1651,13 @@ mod test {
16181651

16191652
// Test if an error is returned when request is not sent by creator
16201653
{
1621-
let auth = Auth {
1654+
let auth = Extension(Auth {
16221655
era: 0,
16231656
uid: IDS[&LEADER],
16241657
chain: campaign_context.chain.clone(),
1625-
};
1626-
1627-
let req = Request::builder()
1628-
.extension(auth)
1629-
.extension(campaign_context.clone())
1630-
.body(Body::empty())
1631-
.expect("Should build Request");
1658+
});
16321659

1633-
let res = close_campaign(req, &app)
1660+
let res = close_campaign_axum(app.clone(), auth, campaign_context.clone())
16341661
.await
16351662
.expect_err("Should return error for Bad Campaign");
16361663

0 commit comments

Comments
 (0)