Skip to content

Commit 1d62352

Browse files
authored
Merge pull request #211 from Wetshakat/feat/Missing-Unit-Tests-for-Critical-Functions
Missing Unit Tests for Critical Functions
2 parents f48c978 + c4a34d0 commit 1d62352

File tree

211 files changed

+58711
-868
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

211 files changed

+58711
-868
lines changed

.github/workflows/ci.yml

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,49 @@ jobs:
3434
- name: Build WASM (release)
3535
run: cargo build --target wasm32-unknown-unknown --release
3636

37+
- name: Run tests
38+
run: cargo test --workspace
39+
40+
- name: Clippy
41+
run: cargo clippy --all-targets --all-features -- -D warnings
42+
43+
coverage:
44+
runs-on: ubuntu-latest
45+
needs: rust
46+
steps:
47+
- uses: actions/checkout@v4
48+
49+
- name: Install Rust toolchain
50+
uses: dtolnay/rust-toolchain@stable
51+
52+
- name: Cache cargo
53+
uses: Swatinem/rust-cache@v2
54+
55+
- name: Install cargo-tarpaulin
56+
run: cargo install cargo-tarpaulin
57+
58+
- name: Generate coverage report
59+
run: |
60+
cargo tarpaulin \
61+
--workspace \
62+
--out xml \
63+
--out html \
64+
--output-dir coverage \
65+
--skip-clean \
66+
--exclude-files "*/tests/*" "*/test_*" \
67+
--timeout 300
68+
69+
- name: Upload coverage to Codecov
70+
uses: codecov/codecov-action@v4
71+
with:
72+
files: coverage/cobertura.xml
73+
fail_ci_if_error: false
74+
75+
- name: Upload coverage artifacts
76+
uses: actions/upload-artifact@v4
77+
with:
78+
name: coverage-report
79+
path: coverage/
3780
- name: Run tests with coverage
3881
run: |
3982
cargo llvm-cov --workspace --lib --bins --tests --all-features --lcov --output-path lcov.info

contracts/teachlink/src/lib.rs

Lines changed: 214 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,101 @@
11
//! TeachLink Soroban smart contract — entry point.
22
//!
3+
//! // Create atomic swap
4+
//! let swap_id = TeachLinkBridge::initiate_atomic_swap(env, params);
5+
//! ```
6+
//!
7+
//! # Authorization
8+
//!
9+
//! Most state-changing functions require authorization:
10+
//! - Admin functions require the admin address
11+
//! - User functions require the user's address
12+
//! - Validator functions require validator authorization
13+
//! - Escrow functions require appropriate party authorization
14+
15+
#![no_std]
16+
#![allow(clippy::unreadable_literal)]
17+
#![allow(clippy::must_use_candidate)]
18+
#![allow(clippy::missing_panics_doc)]
19+
#![allow(clippy::missing_errors_doc)]
20+
#![allow(clippy::needless_pass_by_value)]
21+
#![allow(clippy::too_many_arguments)]
22+
#![allow(clippy::doc_markdown)]
23+
#![allow(clippy::trivially_copy_pass_by_ref)]
24+
#![allow(clippy::needless_borrow)]
25+
26+
use soroban_sdk::{contract, contractimpl, Address, Bytes, Env, Map, String, Symbol, Vec};
27+
28+
mod analytics;
29+
mod arbitration;
30+
mod assessment;
31+
mod atomic_swap;
32+
mod audit;
33+
mod bft_consensus;
34+
mod bridge;
35+
mod emergency;
36+
mod errors;
37+
mod escrow;
38+
mod escrow_analytics;
39+
mod events;
40+
mod insurance;
41+
// FUTURE: Implement governance module (tracked in TRACKING.md)
42+
// mod governance;
43+
// mod learning_paths;
44+
mod liquidity;
45+
mod message_passing;
46+
mod mobile_platform;
47+
mod multichain;
48+
mod notification;
49+
mod notification_events_basic;
50+
// mod content_quality;
51+
// NOTE: notification_tests disabled — tests access storage outside contract
52+
// context (missing env.as_contract wrapper). See Issue #162.
53+
// mod notification_tests;
54+
mod backup;
55+
mod notification_types;
56+
mod performance;
57+
mod provenance;
58+
mod reporting;
59+
mod reputation;
60+
mod rewards;
61+
mod score;
62+
mod slashing;
63+
mod social_learning;
64+
mod storage;
65+
mod tokenization;
66+
mod types;
67+
pub mod validation;
68+
pub mod property_based_tests;
69+
70+
pub use crate::types::{
71+
ColorBlindMode, ComponentConfig, DeviceInfo, FeedbackCategory, FocusStyle, FontSize,
72+
LayoutDensity, MobileAccessibilitySettings, MobilePreferences, MobileProfile, NetworkType,
73+
OnboardingStage, OnboardingStatus, ThemePreference, UserFeedback, VideoQuality,
74+
};
75+
pub use assessment::{
76+
Assessment, AssessmentSettings, AssessmentSubmission, Question, QuestionType,
77+
};
78+
pub use errors::{BridgeError, EscrowError, MobilePlatformError, RewardsError};
79+
pub use types::{
80+
AlertConditionType, AlertRule, ArbitratorProfile, AtomicSwap, AuditRecord, BackupManifest,
81+
BackupSchedule, BridgeFeeStructure, BridgeMetrics, BridgeProposal, BridgeTransaction,
82+
CachedBridgeSummary, ChainConfig, ChainMetrics, CircuitBreaker, ComplianceReport,
83+
ConsensusState, ContentMetadata, ContentToken, ContentTokenParameters, ContentType,
84+
Contribution, ContributionType, CrossChainMessage, CrossChainPacket, DashboardAnalytics,
85+
DisputeOutcome, EmergencyState, Escrow, EscrowMetrics, EscrowParameters, EscrowRole,
86+
EscrowSigner, EscrowStatus, LiquidityPool, MultiChainAsset, NotificationChannel,
87+
NotificationContent, NotificationPreference, NotificationSchedule, NotificationTemplate,
88+
NotificationTracking, OperationType, PacketStatus, ProposalStatus, ProvenanceRecord,
89+
RecoveryRecord, ReportComment, ReportSchedule, ReportSnapshot, ReportTemplate, ReportType,
90+
ReportUsage, RewardRate, RewardType, RtoTier, SlashingReason, SlashingRecord, SwapStatus,
91+
TransferType, UserNotificationSettings, UserReputation, UserReward, ValidatorInfo,
92+
ValidatorReward, ValidatorSignature, VisualizationDataPoint,
93+
};
94+
95+
/// TeachLink main contract.
96+
///
97+
/// This contract provides entry points for all TeachLink functionality
98+
/// including bridging, rewards, escrow, tokenization, and reputation.
399
4100
pub mod validation;
5101

@@ -1033,6 +1129,16 @@ impl TeachLinkBridge {
10331129
liquidity::LiquidityManager::get_available_liquidity(&env, chain_id)
10341130
}
10351131

1132+
/// Get fee structure
1133+
pub fn get_fee_structure(env: Env) -> BridgeFeeStructure {
1134+
liquidity::LiquidityManager::get_fee_structure(&env)
1135+
}
1136+
1137+
/// Check if pool has sufficient liquidity
1138+
pub fn has_sufficient_liquidity(env: Env, chain_id: u32, amount: i128) -> bool {
1139+
liquidity::LiquidityManager::has_sufficient_liquidity(&env, chain_id, amount)
1140+
}
1141+
10361142
// ========== Message Passing Functions ==========
10371143

10381144
/// Send a cross-chain packet
@@ -1380,6 +1486,47 @@ impl TeachLinkBridge {
13801486
emergency::EmergencyManager::get_emergency_state(&env)
13811487
}
13821488

1489+
/// Check circuit breaker for a transaction
1490+
pub fn check_circuit_breaker(env: Env, chain_id: u32, amount: i128) -> Result<(), BridgeError> {
1491+
emergency::EmergencyManager::check_circuit_breaker(&env, chain_id, amount)
1492+
}
1493+
1494+
/// Reset circuit breaker for a chain
1495+
pub fn reset_circuit_breaker(
1496+
env: Env,
1497+
chain_id: u32,
1498+
resetter: Address,
1499+
) -> Result<(), BridgeError> {
1500+
emergency::EmergencyManager::reset_circuit_breaker(&env, chain_id, resetter)
1501+
}
1502+
1503+
/// Get circuit breaker state
1504+
pub fn get_circuit_breaker(env: Env, chain_id: u32) -> Option<CircuitBreaker> {
1505+
emergency::EmergencyManager::get_circuit_breaker(&env, chain_id)
1506+
}
1507+
1508+
/// Get all paused chains
1509+
pub fn get_paused_chains(env: Env) -> Vec<u32> {
1510+
emergency::EmergencyManager::get_paused_chains(&env)
1511+
}
1512+
1513+
/// Update circuit breaker limits
1514+
pub fn update_circuit_breaker_limits(
1515+
env: Env,
1516+
chain_id: u32,
1517+
max_daily_volume: i128,
1518+
max_transaction_amount: i128,
1519+
updater: Address,
1520+
) -> Result<(), BridgeError> {
1521+
emergency::EmergencyManager::update_circuit_breaker_limits(
1522+
&env,
1523+
chain_id,
1524+
max_daily_volume,
1525+
max_transaction_amount,
1526+
updater,
1527+
)
1528+
}
1529+
13831530
// ========== Audit and Compliance Functions ==========
13841531

13851532
/// Create an audit record
@@ -1460,6 +1607,73 @@ impl TeachLinkBridge {
14601607
audit::AuditManager::get_compliance_report(&env, report_id)
14611608
}
14621609

1610+
/// Get audit record count
1611+
pub fn get_audit_count(env: Env) -> u64 {
1612+
audit::AuditManager::get_audit_count(&env)
1613+
}
1614+
1615+
/// Get audit records by operation type
1616+
pub fn get_audit_records_by_type(
1617+
env: Env,
1618+
operation_type: types::OperationType,
1619+
) -> Vec<AuditRecord> {
1620+
audit::AuditManager::get_audit_records_by_type(&env, operation_type)
1621+
}
1622+
1623+
/// Get audit records by operator
1624+
pub fn get_audit_records_by_operator(env: Env, operator: Address) -> Vec<AuditRecord> {
1625+
audit::AuditManager::get_audit_records_by_operator(&env, operator)
1626+
}
1627+
1628+
/// Get audit records by time range
1629+
pub fn get_audit_records_by_time(env: Env, start_time: u64, end_time: u64) -> Vec<AuditRecord> {
1630+
audit::AuditManager::get_audit_records_by_time(&env, start_time, end_time)
1631+
}
1632+
1633+
/// Get recent audit records
1634+
pub fn get_recent_audit_records(env: Env, count: u32) -> Vec<AuditRecord> {
1635+
audit::AuditManager::get_recent_audit_records(&env, count)
1636+
}
1637+
1638+
/// Clear old audit records
1639+
pub fn clear_old_records(
1640+
env: Env,
1641+
before_timestamp: u64,
1642+
admin: Address,
1643+
) -> Result<u32, BridgeError> {
1644+
audit::AuditManager::clear_old_records(&env, before_timestamp, admin)
1645+
}
1646+
1647+
/// Log bridge operation
1648+
pub fn log_bridge_operation(
1649+
env: Env,
1650+
is_outgoing: bool,
1651+
operator: Address,
1652+
amount: i128,
1653+
chain_id: u32,
1654+
tx_hash: Bytes,
1655+
) -> Result<u64, BridgeError> {
1656+
audit::AuditManager::log_bridge_operation(
1657+
&env,
1658+
is_outgoing,
1659+
operator,
1660+
amount,
1661+
chain_id,
1662+
tx_hash,
1663+
)
1664+
}
1665+
1666+
/// Log emergency operation
1667+
pub fn log_emergency_operation(
1668+
env: Env,
1669+
is_pause: bool,
1670+
operator: Address,
1671+
reason: Bytes,
1672+
tx_hash: Bytes,
1673+
) -> Result<u64, BridgeError> {
1674+
audit::AuditManager::log_emergency_operation(&env, is_pause, operator, reason, tx_hash)
1675+
}
1676+
14631677
// ========== Atomic Swap Functions ==========
14641678

14651679
/// Initiate an atomic swap

contracts/teachlink/src/notification_tests.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ pub mod notification_tests {
77
use crate::notification::*;
88
use crate::notification_types::*;
99
use crate::storage::*;
10-
use soroban_sdk::{Address, Bytes, Env, Map, String, Vec};
10+
use soroban_sdk::{testutils::Address as _, Address, Bytes, Env, Map, String, Vec};
1111

1212
// Helper function to create test addresses
1313
fn create_test_address(env: &Env, id: u8) -> Address {

0 commit comments

Comments
 (0)