Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
177 changes: 177 additions & 0 deletions contracts/escrow/src/tests/match_validation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -285,6 +285,183 @@ fn test_tournament_match_requires_organizer_authorization() {
assert!(result.is_err(), "registered organizer must authorize the match");
}

#[test]
fn test_create_match_below_minimum_stake_rejected() {
let (env, contract_id, _oracle, player1, player2, token, admin) = setup();
let client = EscrowContractClient::new(&env, &contract_id);

client.set_minimum_stake(&admin, &100);

let result = client.try_create_match(
&player1,
&player2,
&99,
&token,
&String::from_str(&env, "b1a2c3d4"),
&Platform::Lichess,
);

assert_eq!(
result,
Err(Ok(Error::InvalidAmount)),
"stake below configured minimum must be rejected"
);
}

#[test]
fn test_create_match_above_maximum_stake_rejected() {
let (env, contract_id, _oracle, player1, player2, token, admin) = setup();
let client = EscrowContractClient::new(&env, &contract_id);

client.set_maximum_stake(&admin, &500);

let result = client.try_create_match(
&player1,
&player2,
&501,
&token,
&String::from_str(&env, "c2b3d4e5"),
&Platform::Lichess,
);

assert_eq!(
result,
Err(Ok(Error::InvalidAmount)),
"stake above configured maximum must be rejected"
);
}

#[test]
fn test_create_match_at_stake_boundaries_accepted() {
let (env, contract_id, _oracle, player1, player2, token, admin) = setup();
let client = EscrowContractClient::new(&env, &contract_id);

client.set_minimum_stake(&admin, &100);
client.set_maximum_stake(&admin, &500);

let at_minimum = client.try_create_match(
&player1,
&player2,
&100,
&token,
&String::from_str(&env, "d3c4e5f6"),
&Platform::Lichess,
);
assert!(
at_minimum.is_ok(),
"stake exactly at the configured minimum must be accepted"
);

let at_maximum = client.try_create_match(
&player1,
&player2,
&500,
&token,
&String::from_str(&env, "e4d5f6a7"),
&Platform::Lichess,
);
assert!(
at_maximum.is_ok(),
"stake exactly at the configured maximum must be accepted"
);
}

#[test]
fn test_create_match_with_only_minimum_configured() {
let (env, contract_id, _oracle, player1, player2, token, admin) = setup();
let client = EscrowContractClient::new(&env, &contract_id);

client.set_minimum_stake(&admin, &100);

let below = client.try_create_match(
&player1,
&player2,
&99,
&token,
&String::from_str(&env, "f5e6a7b8"),
&Platform::Lichess,
);
assert_eq!(
below,
Err(Ok(Error::InvalidAmount)),
"stake below configured minimum must be rejected"
);

let at_minimum = client.try_create_match(
&player1,
&player2,
&100,
&token,
&String::from_str(&env, "a6f7b8c9"),
&Platform::Lichess,
);
assert!(
at_minimum.is_ok(),
"stake exactly at the configured minimum must be accepted"
);

let above_minimum = client.try_create_match(
&player1,
&player2,
&10_000,
&token,
&String::from_str(&env, "b7a8c9d0"),
&Platform::Lichess,
);
assert!(
above_minimum.is_ok(),
"stake above the minimum must be accepted when no maximum is configured"
);
}

#[test]
fn test_create_match_with_only_maximum_configured() {
let (env, contract_id, _oracle, player1, player2, token, admin) = setup();
let client = EscrowContractClient::new(&env, &contract_id);

client.set_maximum_stake(&admin, &500);

let above = client.try_create_match(
&player1,
&player2,
&501,
&token,
&String::from_str(&env, "c8b9d0e1"),
&Platform::Lichess,
);
assert_eq!(
above,
Err(Ok(Error::InvalidAmount)),
"stake above configured maximum must be rejected"
);

let at_maximum = client.try_create_match(
&player1,
&player2,
&500,
&token,
&String::from_str(&env, "d9c0e1f2"),
&Platform::Lichess,
);
assert!(
at_maximum.is_ok(),
"stake exactly at the configured maximum must be accepted"
);

let below_maximum = client.try_create_match(
&player1,
&player2,
&1,
&token,
&String::from_str(&env, "e0d1f2a3"),
&Platform::Lichess,
);
assert!(
below_maximum.is_ok(),
"stake below the maximum must be accepted when no minimum is configured"
);
}

#[test]
fn test_create_match_with_zero_stake_rejected() {
let (env, contract_id, _oracle, player1, player2, token, _admin) = setup();
Expand Down
6 changes: 4 additions & 2 deletions frontend/src/hooks/useMatchStatus.ts
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,8 @@ export function useMatchStatus(
}, interval);
}

// Cleanup function
// Cleanup function: always clear the polling interval so no timer
// survives unmount or a dependency change.
return () => {
if (intervalRef.current) {
clearInterval(intervalRef.current);
Expand All @@ -219,7 +220,8 @@ export function useMatchStatus(
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [matchId, interval, enabled, fetchMatch, shouldStopPolling]);

// Cleanup on unmount
// Track mount status so in-flight fetchMatch promises cannot setState
// after unmount, and clear any dangling interval on unmount.
useEffect(() => {
isMountedRef.current = true;

Expand Down
Loading
Loading