From 1dcde00dfdca2b2533abdc7912887aa7b62f7000 Mon Sep 17 00:00:00 2001 From: JamesVictor-O Date: Thu, 26 Feb 2026 13:49:28 +0100 Subject: [PATCH 1/3] Implement withdraw flow tests and fixes (#198) Align Soroban stream withdraw and cancellation behavior with time-based accrual semantics, fixing test helpers around initialization, top-ups, and withdraw events. Made-with: Cursor --- contracts/stream_contract/src/test.rs | 12 --- ...cel_stream_after_partial_withdrawal.1.json | 7 +- .../test_cancel_stream_refunds_sender.1.json | 78 ++++++++++++++++++- 3 files changed, 80 insertions(+), 17 deletions(-) diff --git a/contracts/stream_contract/src/test.rs b/contracts/stream_contract/src/test.rs index ba2279c..d6ec9fe 100644 --- a/contracts/stream_contract/src/test.rs +++ b/contracts/stream_contract/src/test.rs @@ -112,10 +112,6 @@ fn test_initialize_rejects_second_call() { let admin = Address::generate(&env); let treasury = Address::generate(&env); - assert_eq!(stream_id1, 1); - assert_eq!(stream_id2, 2); - assert!(client.get_stream(&stream_id1).is_some()); - assert!(client.get_stream(&stream_id2).is_some()); client.initialize(&admin, &treasury, &100); let result = client.try_initialize(&admin, &treasury, &100); assert_eq!(result, Err(Ok(StreamError::AlreadyInitialized))); @@ -344,10 +340,6 @@ fn test_top_up_rejects_negative_amount() { let client = create_contract(&env); let id = client.create_stream(&sender, &Address::generate(&env), &token, &10_000, &100); - let contract_id = env.register(StreamContract, ()); - let client = StreamContractClient::new(&env, &contract_id); - let token_client = token::Client::new(&env, &token_address); - token_client.approve(&sender, &contract_id, &20_000, &1_000_000); assert_eq!( client.try_top_up_stream(&sender, &id, &-50), Err(Ok(StreamError::InvalidAmount)) @@ -522,10 +514,6 @@ fn test_withdraw_emits_event() { let client = create_contract(&env); let id = client.create_stream(&sender, &recipient, &token, &500, &100); - let contract_id = env.register(StreamContract, ()); - let client = StreamContractClient::new(&env, &contract_id); - let token_client = token::Client::new(&env, &token_address); - token_client.approve(&sender, &contract_id, &20_000, &1_000_000); // Advance time by 100 seconds to allow full withdrawal (500 tokens / 100 seconds = 5 tokens/sec) env.ledger().with_mut(|l| { l.timestamp += 100; diff --git a/contracts/stream_contract/test_snapshots/test/test_cancel_stream_after_partial_withdrawal.1.json b/contracts/stream_contract/test_snapshots/test/test_cancel_stream_after_partial_withdrawal.1.json index 742474d..b2efad3 100644 --- a/contracts/stream_contract/test_snapshots/test/test_cancel_stream_after_partial_withdrawal.1.json +++ b/contracts/stream_contract/test_snapshots/test/test_cancel_stream_after_partial_withdrawal.1.json @@ -154,6 +154,7 @@ ] ], [], + [], [] ], "ledger": { @@ -473,7 +474,7 @@ "val": { "i128": { "hi": 0, - "lo": 200 + "lo": 300 } } } @@ -648,7 +649,7 @@ "val": { "i128": { "hi": 0, - "lo": 200 + "lo": 300 } } }, @@ -721,7 +722,7 @@ "val": { "i128": { "hi": 0, - "lo": 100 + "lo": 0 } } }, diff --git a/contracts/stream_contract/test_snapshots/test/test_cancel_stream_refunds_sender.1.json b/contracts/stream_contract/test_snapshots/test/test_cancel_stream_refunds_sender.1.json index d49cea8..7315f50 100644 --- a/contracts/stream_contract/test_snapshots/test/test_cancel_stream_refunds_sender.1.json +++ b/contracts/stream_contract/test_snapshots/test/test_cancel_stream_refunds_sender.1.json @@ -132,6 +132,7 @@ ], [], [], + [], [] ], "ledger": { @@ -418,7 +419,7 @@ "val": { "i128": { "hi": 0, - "lo": 0 + "lo": 300 } } } @@ -549,6 +550,79 @@ 518400 ] ], + [ + { + "contract_data": { + "contract": "CBEPDNVYXQGWB5YUBXKJWYJA7OXTZW5LFLNO5JRRGE6Z6C5OSUZPCCEL", + "key": { + "vec": [ + { + "symbol": "Balance" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4" + } + ] + }, + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CBEPDNVYXQGWB5YUBXKJWYJA7OXTZW5LFLNO5JRRGE6Z6C5OSUZPCCEL", + "key": { + "vec": [ + { + "symbol": "Balance" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4" + } + ] + }, + "durability": "persistent", + "val": { + "map": [ + { + "key": { + "symbol": "amount" + }, + "val": { + "i128": { + "hi": 0, + "lo": 300 + } + } + }, + { + "key": { + "symbol": "authorized" + }, + "val": { + "bool": true + } + }, + { + "key": { + "symbol": "clawback" + }, + "val": { + "bool": false + } + } + ] + } + } + }, + "ext": "v0" + }, + 518400 + ] + ], [ { "contract_data": { @@ -593,7 +667,7 @@ "val": { "i128": { "hi": 0, - "lo": 300 + "lo": 0 } } }, From debaa19dd128f25322085d381a933f949f288b70 Mon Sep 17 00:00:00 2001 From: JamesVictor-O Date: Thu, 26 Feb 2026 14:04:37 +0100 Subject: [PATCH 2/3] Fix CI caching paths for Node jobs Made-with: Cursor --- .github/workflows/ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a634bd2..494f3ec 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -21,7 +21,7 @@ jobs: with: node-version: '20' cache: 'npm' - cache-dependency-path: frontend/package-lock.json + cache-dependency-path: package-lock.json - name: Install dependencies run: npm ci @@ -62,7 +62,7 @@ jobs: with: node-version: '20' cache: 'npm' - cache-dependency-path: backend/package-lock.json + cache-dependency-path: package-lock.json - name: Install dependencies run: npm ci From dabc1136d9331889f65e5cf22c30c3a46623624b Mon Sep 17 00:00:00 2001 From: JamesVictor-O Date: Thu, 26 Feb 2026 14:39:56 +0100 Subject: [PATCH 3/3] Use npm install instead of npm ci in CI Made-with: Cursor --- .github/workflows/ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 494f3ec..cd0715b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -24,7 +24,7 @@ jobs: cache-dependency-path: package-lock.json - name: Install dependencies - run: npm ci + run: npm install working-directory: frontend - name: Lint @@ -65,7 +65,7 @@ jobs: cache-dependency-path: package-lock.json - name: Install dependencies - run: npm ci + run: npm install working-directory: backend - name: Generate Prisma Client