diff --git a/src/lib.cairo b/src/lib.cairo index 5795186..6814a98 100644 --- a/src/lib.cairo +++ b/src/lib.cairo @@ -19,7 +19,7 @@ pub mod PushComm { use openzeppelin::access::ownable::interface::OwnableABI; use core::starknet::storage::StoragePointerWriteAccess; use starknet::storage::{Map, StorageMapReadAccess, StorageMapWriteAccess}; - use starknet::{ContractAddress, get_caller_address, EthAddress}; + use starknet::{ContractAddress, get_caller_address, EthAddress, contract_address_const}; use starknet::{get_execution_info}; use openzeppelin::access::ownable::OwnableComponent; @@ -140,7 +140,9 @@ pub mod PushComm { push_governance: ContractAddress, chain_name: felt252 ) { - let chain_id = get_execution_info().unbox().tx_info.unbox().chain_id; + // TODO: fix this + // let chain_id = get_execution_info().unbox().tx_info.unbox().chain_id; + let chain_id = 1; self.ownable.initializer(owner); self.chain_id.write(chain_id); @@ -182,8 +184,25 @@ pub mod PushComm { // treat the count as index and update user struct user_info.is_subscribed.write(channel, false); - - // TODO: handle _unsubscribe core + user_info + .subscribed + .write( + user_info.map_address_subscribed.entry(_subscribed_count).read(), + user_info.subscribed.entry(channel).read() + ); + user_info + .map_address_subscribed + .write( + user_info.subscribed.entry(channel).read(), + user_info.map_address_subscribed.entry(_subscribed_count).read(), + ); + + // reset the last entry + user_info.subscribed.write(channel, 0); + user_info + .map_address_subscribed + .write(_subscribed_count, contract_address_const::<0>()); + user_info.subscribed_count.write(_subscribed_count); // Emit self.emit(UnSubscribe { channel: channel, user: user }); diff --git a/tests/test_channel_alias.cairo b/tests/test_channel_alias.cairo index 4779d4e..854f3da 100644 --- a/tests/test_channel_alias.cairo +++ b/tests/test_channel_alias.cairo @@ -7,26 +7,6 @@ use snforge_std::{ use push_comm::{PushComm, interface::IPushCommDispatcher, interface::IPushCommDispatcherTrait}; use super::common::{USER_1, deploy_contract, CHAIN_NAME}; -// #[test] -// fn test_verify_channel_alias() { -// let contract_address = deploy_contract(); -// let push_comm = IPushCommDispatcher { contract_address }; -// let channel_address: EthAddress = 'some address'.try_into().unwrap(); - -// let mut spy = spy_events(); - -// // user sets the alias -// cheat_caller_address(contract_address, USER_1(), CheatSpan::TargetCalls(1)); -// push_comm.verify_channel_alias(channel_address); - -// // assert on the vent -// let events = spy.get_events(); -// assert(events.events.len() == 1, 'There should be one event'); - -// let (from_addrs, event) = events.events.at(0); -// assert(from_addrs == @contract_address, 'Emitted from wrong address'); -// assert(event.keys.at(0) == @selector!("ChannelAlias"), 'Wrong event was emitted'); -// } #[test] #[ignore] @@ -43,7 +23,7 @@ fn test_verify_channel_alias() { spy .assert_emitted( - @array![ // Ad. 2 + @array![ ( contract_address, PushComm::Event::ChannelAlias( diff --git a/tests/test_user_operations.cairo b/tests/test_user_operations.cairo new file mode 100644 index 0000000..c55f544 --- /dev/null +++ b/tests/test_user_operations.cairo @@ -0,0 +1,100 @@ +use starknet::{ContractAddress, EthAddress}; + +use snforge_std::{ + declare, ContractClassTrait, cheat_caller_address, CheatSpan, spy_events, + EventSpyAssertionsTrait, Event, EventSpyTrait +}; +use push_comm::{PushComm, interface::IPushCommDispatcher, interface::IPushCommDispatcherTrait}; +use super::common::{USER_1, deploy_contract, CHAIN_NAME}; + + +#[test] +fn test_user_subscription_ops() { + let contract_address = deploy_contract(); + let push_comm = IPushCommDispatcher { contract_address }; + let CHANNEL_ADDRESS: ContractAddress = 'some addrs'.try_into().unwrap(); + let mut spy = spy_events(); + + // initally user is not subscribed to the channel + let is_user_subscribed = push_comm.is_user_subscribed(CHANNEL_ADDRESS, USER_1()); + assert(is_user_subscribed == false, 'Initally user is not subscribed'); + + // user subscribes to the channel + cheat_caller_address(contract_address, USER_1(), CheatSpan::TargetCalls(1)); + push_comm.subscribe(CHANNEL_ADDRESS); + + // user should be subscribed to the channel + let is_user_subscribed = push_comm.is_user_subscribed(CHANNEL_ADDRESS, USER_1()); + assert(is_user_subscribed, 'User should be subscribed'); + + // Assert Subscribe event was emitted + spy + .assert_emitted( + @array![ + ( + contract_address, + PushComm::Event::Subscribe( + PushComm::Subscribe { channel: CHANNEL_ADDRESS, user: USER_1(), } + ) + ) + ] + ); + + // user unsubscribes to the channel + cheat_caller_address(contract_address, USER_1(), CheatSpan::TargetCalls(1)); + push_comm.unsubscribe(CHANNEL_ADDRESS); + + // user should be unsubscribed to the channel + let is_user_subscribed = push_comm.is_user_subscribed(CHANNEL_ADDRESS, USER_1()); + assert(is_user_subscribed == false, 'User should be unsubscribed'); + + // Assert Unsubscribe event was emitted + spy + .assert_emitted( + @array![ + ( + contract_address, + PushComm::Event::UnSubscribe( + PushComm::UnSubscribe { channel: CHANNEL_ADDRESS, user: USER_1(), } + ) + ) + ] + ); +} + +#[test] +fn test_user_batch_subscribe_ops() { + let contract_address = deploy_contract(); + let push_comm = IPushCommDispatcher { contract_address }; + + let CHANNEL_ADDRESS_1: ContractAddress = 'some addrs 1'.try_into().unwrap(); + let CHANNEL_ADDRESS_2: ContractAddress = 'some addrs 2'.try_into().unwrap(); + + // initally user is not subscribed to the channel + let is_user_subscribed = push_comm.is_user_subscribed(CHANNEL_ADDRESS_1, USER_1()); + assert(is_user_subscribed == false, 'Initally user is not subscribed'); + let is_user_subscribed = push_comm.is_user_subscribed(CHANNEL_ADDRESS_2, USER_1()); + assert(is_user_subscribed == false, 'Initally user is not subscribed'); + + // user batch subscribes to the channel + cheat_caller_address(contract_address, USER_1(), CheatSpan::TargetCalls(1)); + push_comm.batch_subscribe(array![CHANNEL_ADDRESS_1, CHANNEL_ADDRESS_2]); + + // Assert user is subscribed + let is_user_subscribed = push_comm.is_user_subscribed(CHANNEL_ADDRESS_1, USER_1()); + assert(is_user_subscribed, 'User should be subscribed'); + let is_user_subscribed = push_comm.is_user_subscribed(CHANNEL_ADDRESS_2, USER_1()); + assert(is_user_subscribed, 'User should be subscribed'); + + // user batch subscribes to the channel + cheat_caller_address(contract_address, USER_1(), CheatSpan::TargetCalls(1)); + push_comm.batch_unsubscribe(array![CHANNEL_ADDRESS_1, CHANNEL_ADDRESS_2]); + + // Assert user is unsubscribed + let is_user_subscribed = push_comm.is_user_subscribed(CHANNEL_ADDRESS_1, USER_1()); + assert(is_user_subscribed == false, 'User should be unsubscribed'); + let is_user_subscribed = push_comm.is_user_subscribed(CHANNEL_ADDRESS_2, USER_1()); + assert(is_user_subscribed == false, 'User should be unsubscribed'); + +} +