diff --git a/src/base/constants/errors.cairo b/src/base/constants/errors.cairo index 4a0c108..81d41dd 100644 --- a/src/base/constants/errors.cairo +++ b/src/base/constants/errors.cairo @@ -20,8 +20,10 @@ pub mod Errors { pub const SELF_FOLLOWING: felt252 = 'Karst: self follow is forbidden'; pub const ALREADY_REACTED: felt252 = 'Karst: already react to post!'; pub const TOKEN_DOES_NOT_EXIST: felt252 = 'Karst: token_id does not exist!'; - pub const NOT_CHANNEL_OWNER: felt252 = 'Channel: not channel owner '; + pub const NOT_CHANNEL_OWNER: felt252 = 'Channel: not channel owner'; pub const NOT_CHANNEL_MODERATOR: felt252 = 'Channel: not channel moderator'; pub const NOT_CHANNEL_MEMBER: felt252 = 'Channel: not channel member'; pub const BANNED_FROM_CHANNEL: felt252 = 'Channel: banned from channel'; + pub const CHANNEL_HAS_NO_MEMBER: felt252 = 'Channel has no members'; + pub const UNAUTHORIZED_ACESS: felt252 = 'Karst : Unauthorized access'; } diff --git a/src/channel/channel.cairo b/src/channel/channel.cairo index 4f2fd07..3f8d49a 100644 --- a/src/channel/channel.cairo +++ b/src/channel/channel.cairo @@ -1,18 +1,18 @@ -//TODO make the channel as the componet #[starknet::component] pub mod ChannelComponent { use core::clone::Clone; use core::starknet::{ - ContractAddress, get_caller_address, get_block_timestamp, - storage::{ - StoragePointerWriteAccess, StoragePointerReadAccess, Map, StorageMapReadAccess, - StorageMapWriteAccess - } + ContractAddress, contract_address_const, get_caller_address, get_block_timestamp + }; + use starknet::storage::{ + StoragePointerReadAccess, StoragePointerWriteAccess, StoragePathEntry, Map, + StorageMapReadAccess, StorageMapWriteAccess, Vec, VecTrait, MutableVecTrait }; use karst::interfaces::IChannel::IChannel; use karst::base::{ constants::errors::Errors::{ - NOT_CHANNEL_OWNER, NOT_CHANNEL_MODERATOR, NOT_CHANNEL_MEMBER, BANNED_FROM_CHANNEL + NOT_CHANNEL_OWNER, NOT_CHANNEL_MODERATOR, NOT_CHANNEL_MEMBER, BANNED_FROM_CHANNEL, + CHANNEL_HAS_NO_MEMBER, UNAUTHORIZED_ACESS }, constants::types::{channelParams, channelMember} }; @@ -20,8 +20,8 @@ pub mod ChannelComponent { pub struct Storage { channels: Map, channel_counter: u256, - channel_members: Map, - channel_moderators: Map<(u256, ContractAddress), bool>, + channel_members: Map<(u256, ContractAddress), channelMember>, + channel_moderators: Map>, } #[derive(Drop, starknet::Event)] @@ -47,12 +47,12 @@ pub mod ChannelComponent { token_id: u256, block_timestamp: u64, } - // this should also contain the IChannel & IChannelNFT implmentation , waht is the self what d. + #[derive(Drop, starknet::Event)] pub struct ChannelModAdded { channel_id: u256, transaction_executor: ContractAddress, - mod_address: ContractAddress, + mod_address: Array, block_timestamp: u64, } @@ -60,7 +60,7 @@ pub mod ChannelComponent { pub struct ChannelModRemoved { channel_id: u256, transaction_executor: ContractAddress, - mod_address: ContractAddress, + mod_address: Array, block_timestamp: u64, } @@ -84,8 +84,6 @@ pub mod ChannelComponent { } - // mnaking the constructor to store the onwer , who can set the moderators - #[embeddable_as(KarstChannel)] impl ChannelImpl< TContractState, +HasComponent, +Drop @@ -125,19 +123,17 @@ pub mod ChannelComponent { /// @param channel_id: The id of the channel fn join_channel(ref self: ComponentState, channel_id: u256) { // check that i prioor not baned - let channel_member: channelMember = self.channel_members.read(get_caller_address()); + let channel_member: channelMember = self + .channel_members + .read((channel_id, get_caller_address())); assert(!channel_member.ban_status, BANNED_FROM_CHANNEL); - - let mut new_channel: channelParams = self.channels.read(channel_id); - new_channel.channel_total_members += 1; - self.channels.write(channel_id, new_channel); - - // calculate the total channel member add +1 is the new member id - + let mut channel: channelParams = self.channels.read(channel_id); + channel.channel_total_members += 1; + self.channels.write(channel_id, channel); self .channel_members .write( - get_caller_address(), + (channel_id, get_caller_address()), channelMember { profile: get_caller_address(), channel_id: channel_id, @@ -165,21 +161,30 @@ pub mod ChannelComponent { /// @dev The user must be a member of the channel fn leave_channel(ref self: ComponentState, channel_id: u256) { assert( - self.channel_members.read(get_caller_address()).channel_id == channel_id, + self + .channel_members + .read((channel_id, get_caller_address())) + .channel_id == channel_id + && self + .channel_members + .read((channel_id, get_caller_address())) + .profile == get_caller_address(), NOT_CHANNEL_MEMBER ); assert( - !self.channel_members.read(get_caller_address()).ban_status, BANNED_FROM_CHANNEL + !self.channel_members.read((channel_id, get_caller_address())).ban_status, + BANNED_FROM_CHANNEL ); - assert(self.channels.read(channel_id).channel_total_members > 1, 'total_member > 1'); + let total_members: u256 = self.channels.read(channel_id).channel_total_members; + assert(total_members > 1, CHANNEL_HAS_NO_MEMBER); self .channel_members .write( - get_caller_address(), + (channel_id, get_caller_address()), channelMember { - profile: get_caller_address(), - // todo , what default channel id should set max but not optimize to store + profile: contract_address_const::<0>(), + // todo , what default channel id should . as 0 can be channel_id channel_id: 10000000, total_publications: 0, channel_token_id: 0, @@ -187,9 +192,9 @@ pub mod ChannelComponent { } ); - let mut new_channel: channelParams = self.channels.read(channel_id); - new_channel.channel_total_members -= 1; - self.channels.write(channel_id, new_channel); + let mut channel: channelParams = self.channels.read(channel_id); + channel.channel_total_members -= 1; + self.channels.write(channel_id, channel); //TODO Delete the mapping at the caller address //TODO : burn the NFT @@ -215,28 +220,40 @@ pub mod ChannelComponent { let channel_member: channelParams = self.channels.read(channel_id); assert( channel_member.channel_owner == get_caller_address() - || self.channel_moderators.read((channel_id, get_caller_address())), - NOT_CHANNEL_MODERATOR + || self.is_channel_mod(get_caller_address(), channel_id), + UNAUTHORIZED_ACESS ); - let mut new_channel: channelParams = self.channels.read(channel_id); - new_channel.channel_metadata_uri = metadata_uri; - self.channels.write(channel_id, new_channel); + let mut channel: channelParams = self.channels.read(channel_id); + channel.channel_metadata_uri = metadata_uri; + self.channels.write(channel_id, channel); } /// @notice Add a moderator to the channel /// @param channel_id: The id of the channel - /// @param moderator: The address of the moderator + /// @param Array: The address of the moderator /// dev only primary moderator/owner can add the moderators fn add_channel_mods( - ref self: ComponentState, channel_id: u256, moderator: ContractAddress + ref self: ComponentState, + channel_id: u256, + moderator: Array ) { assert( self.channels.read(channel_id).channel_owner == get_caller_address(), NOT_CHANNEL_OWNER ); - self.channel_moderators.write((channel_id, moderator), true); + for i in 0 + ..moderator + .len() { + if (!self.is_channel_mod(*moderator.at(i), channel_id)) { + self + .channel_moderators + .entry(channel_id) + .append() + .write(*moderator.at(i)); + } + }; self .emit( ChannelModAdded { @@ -254,15 +271,35 @@ pub mod ChannelComponent { /// @param moderator: The address of the moderator /// dev only primary moderator/owner can remove the moderators fn remove_channel_mods( - ref self: ComponentState, channel_id: u256, moderator: ContractAddress + ref self: ComponentState, + channel_id: u256, + moderator: Array ) { - // let channel_member: channelParams = self.channels.read(channel_id); assert( self.channels.read(channel_id).channel_owner == get_caller_address(), NOT_CHANNEL_OWNER ); - - self.channel_moderators.write((channel_id, moderator), false); + for i in 0 + ..moderator + .len() { + if (self.is_channel_mod(*moderator.at(i), channel_id)) { + let mut channe_moderators = self.channel_moderators.entry(channel_id); + for j in 0 + ..channe_moderators + .len() { + if (channe_moderators.at(j).read() == *moderator.at(i)) { + // todo zero address set + channe_moderators + .at(j) + .write(contract_address_const::<0>()); + } + }; + } + }; + + // remove at the index thus making the best thing which i can made is the person who i + // can make the best place to make the system which is todo + // first know the element and then remove the function and delete the person self .emit( @@ -275,7 +312,6 @@ pub mod ChannelComponent { ) } - /// @notice Set the censorship status of the channel /// @param channel_id: The id of the channel fn set_channel_censorship_status( @@ -286,9 +322,9 @@ pub mod ChannelComponent { self.channels.read(channel_id).channel_owner == get_caller_address(), NOT_CHANNEL_OWNER ); - let mut new_channel: channelParams = self.channels.read(channel_id); - new_channel.channel_censorship = censorship_status; - self.channels.write(channel_id, new_channel); + let mut channel: channelParams = self.channels.read(channel_id); + channel.channel_censorship = censorship_status; + self.channels.write(channel_id, channel); } @@ -305,12 +341,21 @@ pub mod ChannelComponent { // let channel_member: channelParams = self.channels.read(channel_id); assert( self.channels.read(channel_id).channel_owner == get_caller_address() - || self.channel_moderators.read((channel_id, get_caller_address())), - NOT_CHANNEL_MODERATOR + || self.is_channel_mod(get_caller_address(), channel_id), + UNAUTHORIZED_ACESS + ); + // check that channel exits and the profile is a member of the channel + assert( + self.channel_members.read((channel_id, profile)).profile == profile + && self.channel_members.read((channel_id, profile)).channel_id == channel_id, + NOT_CHANNEL_MEMBER ); - let mut new_channel_member: channelMember = self.channel_members.read(profile); - new_channel_member.ban_status = ban_status; - self.channel_members.write(profile, new_channel_member); + + let mut channel_member: channelMember = self + .channel_members + .read((channel_id, profile)); + channel_member.ban_status = ban_status; + self.channel_members.write((channel_id, profile), channel_member); self .emit( @@ -347,7 +392,7 @@ pub mod ChannelComponent { fn is_channel_member( self: @ComponentState, profile: ContractAddress, channel_id: u256 ) -> bool { - let channel_member: channelMember = self.channel_members.read(profile); + let channel_member: channelMember = self.channel_members.read((channel_id, profile)); if (channel_member.channel_id == channel_id) { true } else { @@ -368,7 +413,15 @@ pub mod ChannelComponent { fn is_channel_mod( self: @ComponentState, profile: ContractAddress, channel_id: u256 ) -> bool { - self.channel_moderators.read((channel_id, profile)) + let mut dd = self.channel_moderators.entry(channel_id); + let mut flag: bool = false; + for i in 0..dd.len() { + if (dd.at(i).read() == profile) { + flag = true; + break; + } + }; + flag } fn get_channel_censorship_status( @@ -378,9 +431,10 @@ pub mod ChannelComponent { channel.channel_censorship } - ///TODO introduce new storage for ban status - fn get_ban_status(self: @ComponentState, profile: ContractAddress) -> bool { - let channel_member: channelMember = self.channel_members.read(profile); + fn get_ban_status( + self: @ComponentState, profile: ContractAddress, channel_id: u256 + ) -> bool { + let channel_member: channelMember = self.channel_members.read((channel_id, profile)); channel_member.ban_status } } diff --git a/src/interfaces/IChannel.cairo b/src/interfaces/IChannel.cairo index 2888f5c..b95459e 100644 --- a/src/interfaces/IChannel.cairo +++ b/src/interfaces/IChannel.cairo @@ -10,31 +10,21 @@ pub trait IChannel { fn join_channel(ref self: TState, channel_id: u256); fn leave_channel(ref self: TState, channel_id: u256); fn set_channel_metadata_uri(ref self: TState, channel_id: u256, metadata_uri: ByteArray); - fn add_channel_mods(ref self: TState, channel_id: u256, moderator: ContractAddress); - fn remove_channel_mods(ref self: TState, channel_id: u256, moderator: ContractAddress); + fn add_channel_mods(ref self: TState, channel_id: u256, moderator: Array); + fn remove_channel_mods(ref self: TState, channel_id: u256, moderator: Array); fn set_channel_censorship_status(ref self: TState, channel_id: u256, censorship_status: bool); fn set_ban_status( ref self: TState, channel_id: u256, profile: ContractAddress, ban_status: bool ); - // // ************************************************************************* - // // GETTERS - // // ************************************************************************* + // ************************************************************************* + // GETTERS + // ************************************************************************* fn get_channel(self: @TState, channel_id: u256) -> channelParams; fn get_channel_metadata_uri(self: @TState, channel_id: u256) -> ByteArray; - // so is the profile is channel member or not we have to say that which channel id , i think it - // will be good fn is_channel_member(self: @TState, profile: ContractAddress, channel_id: u256) -> bool; - // what is the means by the paid channel member - // how we can calcualte the get_total_member - fn get_total_members(self: @TState, channel_id: u256) -> u256; - - // we have to pass the channel id how is the ch fn is_channel_mod(self: @TState, profile: ContractAddress, channel_id: u256) -> bool; - - // this one is easy fn get_channel_censorship_status(self: @TState, channel_id: u256) -> bool; - - fn get_ban_status(self: @TState, profile: ContractAddress) -> bool; + fn get_ban_status(self: @TState, profile: ContractAddress, channel_id: u256) -> bool; } diff --git a/tests/test_channel.cairo b/tests/test_channel.cairo index fe3d125..3ea3113 100644 --- a/tests/test_channel.cairo +++ b/tests/test_channel.cairo @@ -5,8 +5,7 @@ use core::option::OptionTrait; use core::starknet::SyscallResultTrait; use core::result::ResultTrait; use core::traits::{TryInto, Into}; -use starknet::{ContractAddress, get_block_timestamp}; - +use starknet::ContractAddress; use snforge_std::{ declare, start_cheat_caller_address, stop_cheat_caller_address, spy_events, @@ -30,7 +29,12 @@ const USER_THREE: felt252 = 'ROB'; const USER_FOUR: felt252 = 'DAN'; const USER_FIVE: felt252 = 'RANDY'; const USER_SIX: felt252 = 'JOE'; - +const MODERATOR1: felt252 = 'MOD1'; +const MODERATOR2: felt252 = 'MOD2'; +const NOTOWNER: felt252 = 'NOTOWNER'; +const NOTMODERATOR: felt252 = 'NOTMODERATOR'; +const MEMBER1: felt252 = 'MEMBER1'; +const MEMBER2: felt252 = 'MEMBER2'; fn __setup__() -> (ContractAddress, u256, ContractAddress, ByteArray) { let nft_contract = declare("KarstNFT").unwrap().contract_class(); @@ -48,19 +52,10 @@ fn __setup__() -> (ContractAddress, u256, ContractAddress, ByteArray) { let (channel_contract_address, _) = channel_contract .deploy(@channel_constructor_calldata) .unwrap_syscall(); - - // declare account let account_class_hash = declare("Account").unwrap().contract_class(); - - // declare follownft let follow_nft_classhash = declare("Follow").unwrap().contract_class(); - - //declare collectnft let collect_nft_classhash = declare("CollectNFT").unwrap().contract_class(); - let dispatcher = IChannelDispatcher { contract_address: channel_contract_address }; - - // create channel for the use1 start_cheat_caller_address(channel_contract_address, USER_ONE.try_into().unwrap()); let mut spy = spy_events(); let metadat_uri: ByteArray = "ipfs://QmSkDCsS32eLpcymxtn1cEn7Rc5hfefLBgfvZyjaYXr4gQ/"; @@ -75,186 +70,394 @@ fn __setup__() -> (ContractAddress, u256, ContractAddress, ByteArray) { channel_censorship: false, } ); + let mut moderator_array = array![ + MODERATOR1.try_into().unwrap(), MODERATOR2.try_into().unwrap() + ]; + dispatcher.add_channel_mods(channel_id, moderator_array); + stop_cheat_caller_address(channel_contract_address); + start_cheat_caller_address(channel_contract_address, MEMBER1.try_into().unwrap()); + dispatcher.join_channel(channel_id); stop_cheat_caller_address(channel_contract_address); + start_cheat_caller_address(channel_contract_address, MEMBER2.try_into().unwrap()); + dispatcher.join_channel(channel_id); + stop_cheat_caller_address(channel_contract_address); return (channel_contract_address, channel_id, USER_ONE.try_into().unwrap(), metadat_uri); } -// leave channel testing +// writing the test for the set_channel_metadata_uri : #[test] -fn test_leave_channel() { - let (channel_contract_address, channel_id, owner, _) = __setup__(); +fn test_set_channel_metadata_uri_check_owner() { + let (channel_contract_address, channel_id, owner, metadata_uri) = __setup__(); let dispatcher = IChannelDispatcher { contract_address: channel_contract_address }; - // to leave the channel first join the channel + let metadat_uri: ByteArray = "ipfs://QmSkDCsS32eLpcymxtn1cEn7Rc5hfefLBgfvZyjaYXr4gH/"; + start_cheat_caller_address(channel_contract_address, owner); + dispatcher.set_channel_metadata_uri(channel_id, metadat_uri.clone()); + stop_cheat_caller_address(channel_contract_address); + let channel_metadata_uri = dispatcher.get_channel_metadata_uri(channel_id); + assert(channel_metadata_uri == metadat_uri, 'invalid channel uri '); +} - start_cheat_caller_address(channel_contract_address, USER_TWO.try_into().unwrap()); - dispatcher.join_channel(channel_id); +#[test] +fn test_set_channel_metadata_uri_check_moderator() { + let (channel_contract_address, channel_id, owner, metadata_uri) = __setup__(); + let dispatcher = IChannelDispatcher { contract_address: channel_contract_address }; + let metadat_uri: ByteArray = "ipfs://QmSkDCsS32eLpcymxtn1cEn7Rc5hfefLBgfvZyjaYXr4gH/"; + start_cheat_caller_address(channel_contract_address, MODERATOR1.try_into().unwrap()); + dispatcher.set_channel_metadata_uri(channel_id, metadat_uri.clone()); stop_cheat_caller_address(channel_contract_address); + // check the metadata uri + let channel_metadata_uri = dispatcher.get_channel_metadata_uri(channel_id); + assert(channel_metadata_uri == metadat_uri, 'invalid channel uri '); +} - start_cheat_caller_address(channel_contract_address, USER_THREE.try_into().unwrap()); - dispatcher.join_channel(channel_id); +#[test] +#[should_panic(expected: ('Karst : Unauthorized access',))] +fn test_set_channel_metadata_uri_check_not_owner_or_moderator() { + let (channel_contract_address, channel_id, owner, metadata_uri) = __setup__(); + let dispatcher = IChannelDispatcher { contract_address: channel_contract_address }; + let metadat_uri: ByteArray = "ipfs://QmSkDCsS32eLpcymxtn1cEn7Rc5hfefLBgfvZyjaYXr4gH/"; + start_cheat_caller_address(channel_contract_address, NOTOWNER.try_into().unwrap()); + dispatcher.set_channel_metadata_uri(channel_id, metadat_uri.clone()); stop_cheat_caller_address(channel_contract_address); +} - start_cheat_caller_address(channel_contract_address, USER_FOUR.try_into().unwrap()); - dispatcher.join_channel(channel_id); + +// writing the test for the add_channel_mods() +#[test] +fn test_add_channel_mods_owner() { + let (channel_contract_address, channel_id, owner, metadata_uri) = __setup__(); + let dispatcher = IChannelDispatcher { contract_address: channel_contract_address }; + let mut moderator_array = array![ + MODERATOR1.try_into().unwrap(), MODERATOR2.try_into().unwrap() + ]; + start_cheat_caller_address(channel_contract_address, owner); + dispatcher.add_channel_mods(channel_id, moderator_array); stop_cheat_caller_address(channel_contract_address); - // check is member + // check the moderator assert( - dispatcher.is_channel_member(USER_TWO.try_into().unwrap(), channel_id) == true, - 'invalid channel member' + dispatcher.is_channel_mod(MODERATOR1.try_into().unwrap(), channel_id) == true, + 'user_two is not mod' ); - - // leave the channel - start_cheat_caller_address(channel_contract_address, USER_TWO.try_into().unwrap()); - dispatcher.leave_channel(channel_id); - stop_cheat_caller_address(channel_contract_address); - - // not the member of that assert( - !dispatcher.is_channel_member(USER_TWO.try_into().unwrap(), channel_id) == true, - 'channel not leaved' + dispatcher.is_channel_mod(MODERATOR2.try_into().unwrap(), channel_id) == true, + 'user_three isnt mod' ); } -// // counting of the member of the channel . #[test] -fn test_total_members() { - let (channel_contract_address, channel_id, owner, _) = __setup__(); +#[should_panic(expected: ('Channel: not channel owner',))] +fn test_add_channel_mods_not_owner() { + let (channel_contract_address, channel_id, owner, metadata_uri) = __setup__(); let dispatcher = IChannelDispatcher { contract_address: channel_contract_address }; - - // join the channel - start_cheat_caller_address(channel_contract_address, USER_TWO.try_into().unwrap()); - dispatcher.join_channel(channel_id); + let mut moderator_array = array![ + MODERATOR1.try_into().unwrap(), MODERATOR2.try_into().unwrap() + ]; + start_cheat_caller_address(channel_contract_address, NOTOWNER.try_into().unwrap()); + dispatcher.add_channel_mods(channel_id, moderator_array); stop_cheat_caller_address(channel_contract_address); +} - // join the channel - start_cheat_caller_address(channel_contract_address, USER_THREE.try_into().unwrap()); - dispatcher.join_channel(channel_id); - stop_cheat_caller_address(channel_contract_address); +// total number of the moderator fucntion is usefull . +// then this test is usefull +// #[test] +// fn test_add_channel_mods_duplicate_moderator() { +// let (channel_contract_address , channel_id , owner , metadata_uri ) = __setup__(); +// let dispatcher = IChannelDispatcher { contract_address: channel_contract_address }; +// let mut moderator_array = array![MODERATOR1.try_into().unwrap() , +// MODERATOR1.try_into().unwrap()]; +// start_cheat_caller_address(channel_contract_address , owner); +// dispatcher.add_channel_mods(channel_id , moderator_array); +// stop_cheat_caller_address(channel_contract_address); +// // check the moderator +// assert( +// dispatcher.is_channel_mod(MODERATOR1.try_into().unwrap(), channel_id) == true, +// 'user_two is not mod' +// ); +// assert( +// dispatcher.is_channel_mod(MODERATOR2.try_into().unwrap(), channel_id) == true, +// 'user_three isnt mod' +// ); + +// // add the moderator again +// start_cheat_caller_address(channel_contract_address , owner); +// dispatcher.add_channel_mods(channel_id , moderator_array); +// stop_cheat_caller_address(channel_contract_address); +// // check the moderator +// let total_mod = dispatcher.total_mod_of_channel(channel_id); - // join the channel - start_cheat_caller_address(channel_contract_address, USER_FOUR.try_into().unwrap()); - dispatcher.join_channel(channel_id); +// assert( +// total_mod.len() == 2 , +// 'user_two is not mod' +// ); +// } + +// now writing the test for the remove channel mods +#[test] +fn test_remove_channel_mods_owner() { + let (channel_contract_address, channel_id, owner, metadata_uri) = __setup__(); + let dispatcher = IChannelDispatcher { contract_address: channel_contract_address }; + let mut moderator_array = array![ + MODERATOR1.try_into().unwrap(), MODERATOR2.try_into().unwrap() + ]; + start_cheat_caller_address(channel_contract_address, owner); + dispatcher.add_channel_mods(channel_id, moderator_array); stop_cheat_caller_address(channel_contract_address); - // join the channel - start_cheat_caller_address(channel_contract_address, USER_FIVE.try_into().unwrap()); - dispatcher.join_channel(channel_id); + // remove the moderator + start_cheat_caller_address(channel_contract_address, owner); + dispatcher.remove_channel_mods(channel_id, array![MODERATOR1.try_into().unwrap()]); stop_cheat_caller_address(channel_contract_address); + // check the moderator + assert( + dispatcher.is_channel_mod(MODERATOR1.try_into().unwrap(), channel_id) == false, + 'user_two is not mod' + ); + assert( + dispatcher.is_channel_mod(MODERATOR2.try_into().unwrap(), channel_id) == true, + 'user_three isnt mod' + ); +} - // join the channel - start_cheat_caller_address(channel_contract_address, USER_SIX.try_into().unwrap()); - dispatcher.join_channel(channel_id); +// not the owner of the channel +#[test] +#[should_panic(expected: ('Channel: not channel owner',))] +fn test_remove_channel_mods_not_owner() { + let (channel_contract_address, channel_id, owner, metadata_uri) = __setup__(); + let dispatcher = IChannelDispatcher { contract_address: channel_contract_address }; + let mut moderator_array = array![ + MODERATOR1.try_into().unwrap(), MODERATOR2.try_into().unwrap() + ]; + start_cheat_caller_address(channel_contract_address, owner); + dispatcher.add_channel_mods(channel_id, moderator_array); stop_cheat_caller_address(channel_contract_address); - // check the total member of the channel - let total_members = dispatcher.get_total_members(channel_id); - assert(total_members == 5, 'invalid total members'); + // remove the moderator + start_cheat_caller_address(channel_contract_address, NOTOWNER.try_into().unwrap()); + dispatcher.remove_channel_mods(channel_id, array![MODERATOR1.try_into().unwrap()]); + stop_cheat_caller_address(channel_contract_address); + // check the moderator + assert( + dispatcher.is_channel_mod(MODERATOR1.try_into().unwrap(), channel_id) == true, + 'user_two is not mod' + ); + assert( + dispatcher.is_channel_mod(MODERATOR2.try_into().unwrap(), channel_id) == true, + 'user_three isnt mod' + ); } - +// also test the moderator is not in the channel #[test] -fn test_adding_modeartor() { - // user 1 is the owner of the channel - let (channel_contract_address, channel_id, owner, _) = __setup__(); +fn test_remove_channel_mods_not_moderator() { + let (channel_contract_address, channel_id, owner, metadata_uri) = __setup__(); let dispatcher = IChannelDispatcher { contract_address: channel_contract_address }; + let mut moderator_array = array![ + MODERATOR1.try_into().unwrap(), MODERATOR2.try_into().unwrap() + ]; + start_cheat_caller_address(channel_contract_address, owner); + dispatcher.add_channel_mods(channel_id, moderator_array); + stop_cheat_caller_address(channel_contract_address); - // let say add the 2 more user 2 and user3 as the moderator + // remove the moderator start_cheat_caller_address(channel_contract_address, owner); - dispatcher.add_channel_mods(channel_id, USER_TWO.try_into().unwrap()); - dispatcher.add_channel_mods(channel_id, USER_THREE.try_into().unwrap()); + dispatcher + .remove_channel_mods( + channel_id, array![NOTMODERATOR.try_into().unwrap(), MODERATOR2.try_into().unwrap()] + ); stop_cheat_caller_address(channel_contract_address); // check the moderator assert( - dispatcher.is_channel_mod(USER_TWO.try_into().unwrap(), channel_id) == true, + dispatcher.is_channel_mod(MODERATOR1.try_into().unwrap(), channel_id) == true, 'user_two is not mod' ); assert( - dispatcher.is_channel_mod(USER_THREE.try_into().unwrap(), channel_id) == true, + dispatcher.is_channel_mod(MODERATOR2.try_into().unwrap(), channel_id) == false, 'user_three isnt mod' ); +} - // // remove the moderator user_two and keep the use three - +// checking about the persistance state of the moderator +#[test] +fn test_remove_channel_mods_persistance_state() { + let (channel_contract_address, channel_id, owner, metadata_uri) = __setup__(); + let dispatcher = IChannelDispatcher { contract_address: channel_contract_address }; + let mut moderator_array = array![ + MODERATOR1.try_into().unwrap(), MODERATOR2.try_into().unwrap() + ]; start_cheat_caller_address(channel_contract_address, owner); - dispatcher.remove_channel_mods(channel_id, USER_TWO.try_into().unwrap()); + dispatcher.add_channel_mods(channel_id, moderator_array.clone()); + dispatcher.remove_channel_mods(channel_id, moderator_array.clone()); stop_cheat_caller_address(channel_contract_address); - // check the moderator assert( - dispatcher.is_channel_mod(USER_TWO.try_into().unwrap(), channel_id) == false, - 'user_two should not be mod' + dispatcher.is_channel_mod(MODERATOR1.try_into().unwrap(), channel_id) == false, + 'user_two is not mod' ); assert( - dispatcher.is_channel_mod(USER_THREE.try_into().unwrap(), channel_id) == true, - 'user_three should be mod' + dispatcher.is_channel_mod(MODERATOR2.try_into().unwrap(), channel_id) == false, + 'user_three isnt mod' ); } -// joining the channel testing +// set censorship to test #[test] -fn test_joining_channel() { - let (channel_contract_address, channel_id, owner, _) = __setup__(); +fn test_set_channel_censorship_status_owner() { + let (channel_contract_address, channel_id, owner, metadata_uri) = __setup__(); + let dispatcher = IChannelDispatcher { contract_address: channel_contract_address }; + start_cheat_caller_address(channel_contract_address, owner); + dispatcher.set_channel_censorship_status(channel_id, true); + stop_cheat_caller_address(channel_contract_address); + // check the censorship status + let censorship_status = dispatcher.get_channel_censorship_status(channel_id); + assert(censorship_status == true, 'invalid censorship status'); +} +// not owner of the channel +#[test] +#[should_panic(expected: ('Channel: not channel owner',))] +fn test_set_channel_censorship_status_not_owner() { + let (channel_contract_address, channel_id, owner, metadata_uri) = __setup__(); + let dispatcher = IChannelDispatcher { contract_address: channel_contract_address }; + start_cheat_caller_address(channel_contract_address, NOTOWNER.try_into().unwrap()); + dispatcher.set_channel_censorship_status(channel_id, true); + stop_cheat_caller_address(channel_contract_address); + // check the censorship status + let censorship_status = dispatcher.get_channel_censorship_status(channel_id); + assert(censorship_status == true, 'invalid censorship status'); +} + +// test for set_ban_status +#[test] +fn test_set_ban_status_owner() { + let (channel_contract_address, channel_id, owner, metadata_uri) = __setup__(); let dispatcher = IChannelDispatcher { contract_address: channel_contract_address }; - // user - start_cheat_caller_address(channel_contract_address, USER_THREE.try_into().unwrap()); - // try to join the channel - dispatcher.join_channel(channel_id); + start_cheat_caller_address(channel_contract_address, owner); + dispatcher.set_ban_status(channel_id, MEMBER1.try_into().unwrap(), true); stop_cheat_caller_address(channel_contract_address); + // check the ban status + let ban_status = dispatcher.get_ban_status(MEMBER1.try_into().unwrap(), channel_id); + assert(ban_status == true, 'invalid ban status'); +} - // is channel member of the channel - start_cheat_caller_address(channel_contract_address, USER_THREE.try_into().unwrap()); - let is_channel_member = dispatcher - .is_channel_member(USER_THREE.try_into().unwrap(), channel_id); - assert(is_channel_member == true, 'invalid channel member'); +#[test] +#[should_panic(expected: ('Karst : Unauthorized access',))] +fn test_set_ban_status_owner_or_moderator() { + let (channel_contract_address, channel_id, owner, metadata_uri) = __setup__(); + let dispatcher = IChannelDispatcher { contract_address: channel_contract_address }; + + start_cheat_caller_address(channel_contract_address, NOTOWNER.try_into().unwrap()); + + dispatcher.set_ban_status(channel_id, MEMBER1.try_into().unwrap(), true); stop_cheat_caller_address(channel_contract_address); } -//todo working fine failed through the contract assert -// if aleready ban does not able to join the channel -// #[test] -// fn test_already_ban_cannot_join_channel() { -// let (channel_contract_address, channel_id, owner, _) = __setup__(); -// let dispatcher = IChannelDispatcher { contract_address: channel_contract_address }; +#[test] +#[should_panic(expected: ('Channel: not channel member',))] +fn test_set_ban_status_profile_is_not_member() { + let (channel_contract_address, channel_id, owner, metadata_uri) = __setup__(); + let dispatcher = IChannelDispatcher { contract_address: channel_contract_address }; + start_cheat_caller_address(channel_contract_address, owner); + dispatcher.set_ban_status(channel_id, USER_THREE.try_into().unwrap(), true); + stop_cheat_caller_address(channel_contract_address); +} -// // moderator -// start_cheat_caller_address(channel_contract_address, owner); -// dispatcher.set_ban_status(channel_id, USER_THREE.try_into().unwrap(), true); -// stop_cheat_caller_address(channel_contract_address); +#[test] +fn test_leave_channel_member() { + let (channel_contract_address, channel_id, owner, _) = __setup__(); + let dispatcher = IChannelDispatcher { contract_address: channel_contract_address }; -// // user -// // cannot able to join -// start_cheat_caller_address(channel_contract_address, USER_THREE.try_into().unwrap()); -// dispatcher.join_channel(channel_id); -// stop_cheat_caller_address(channel_contract_address); + start_cheat_caller_address(channel_contract_address, MEMBER1.try_into().unwrap()); + dispatcher.leave_channel(channel_id); + stop_cheat_caller_address(channel_contract_address); -// // is channel member of the channel + // not the member of that + assert( + !dispatcher.is_channel_member(MEMBER1.try_into().unwrap(), channel_id) == true, + 'channel not leaved' + ); +} -// } #[test] -fn test_channel_member() { +#[should_panic(expected: ('Channel: not channel member',))] +fn test_leave_channel_not_member() { let (channel_contract_address, channel_id, owner, _) = __setup__(); let dispatcher = IChannelDispatcher { contract_address: channel_contract_address }; - start_cheat_caller_address(channel_contract_address, owner); - let is_channel_member = dispatcher.is_channel_member(owner, channel_id); - assert(is_channel_member == true, 'invalid channel member'); + + start_cheat_caller_address(channel_contract_address, USER_FOUR.try_into().unwrap()); + dispatcher.leave_channel(channel_id); + stop_cheat_caller_address(channel_contract_address); +} + + +// joining the channel testing +#[test] +fn test_joining_channel() { + let (channel_contract_address, channel_id, owner, _) = __setup__(); + let dispatcher = IChannelDispatcher { contract_address: channel_contract_address }; + + let is_channel_member = dispatcher.is_channel_member(MEMBER1.try_into().unwrap(), channel_id); + assert(is_channel_member == true, 'invalid channel member 1'); + + let is_channel_member = dispatcher.is_channel_member(MEMBER2.try_into().unwrap(), channel_id); + assert(is_channel_member == true, 'invalid channel member 2'); } + +// // counting of the member of the channel . #[test] -fn test_create_channel() { - let (channel_contract_address, channel_id, _, metadata_uri) = __setup__(); +fn test_joining_channel_total_members() { + let (channel_contract_address, channel_id, owner, _) = __setup__(); + let dispatcher = IChannelDispatcher { contract_address: channel_contract_address }; + // join the channel + start_cheat_caller_address(channel_contract_address, USER_TWO.try_into().unwrap()); + dispatcher.join_channel(channel_id); + stop_cheat_caller_address(channel_contract_address); + + // join the channel + start_cheat_caller_address(channel_contract_address, USER_THREE.try_into().unwrap()); + dispatcher.join_channel(channel_id); + stop_cheat_caller_address(channel_contract_address); + + // join the channel + start_cheat_caller_address(channel_contract_address, USER_FOUR.try_into().unwrap()); + dispatcher.join_channel(channel_id); + stop_cheat_caller_address(channel_contract_address); + + // join the channel + start_cheat_caller_address(channel_contract_address, USER_FIVE.try_into().unwrap()); + dispatcher.join_channel(channel_id); + stop_cheat_caller_address(channel_contract_address); + + // join the channel + start_cheat_caller_address(channel_contract_address, USER_SIX.try_into().unwrap()); + dispatcher.join_channel(channel_id); + stop_cheat_caller_address(channel_contract_address); + + // check the total member of the channel + let total_members = dispatcher.get_total_members(channel_id); + assert(total_members == 7, 'invalid total members'); +} + +#[test] +#[should_panic(expected: ('Channel has no members',))] +fn test_leave_channel_less_then_one() { + let (channel_contract_address, channel_id, owner, _) = __setup__(); let dispatcher = IChannelDispatcher { contract_address: channel_contract_address }; - start_cheat_caller_address(channel_contract_address, USER_ONE.try_into().unwrap()); - let channel_metadata_uri = dispatcher.get_channel_metadata_uri(channel_id); - assert(channel_metadata_uri == metadata_uri, 'invalid channel uri '); + start_cheat_caller_address(channel_contract_address, MEMBER1.try_into().unwrap()); + dispatcher.leave_channel(channel_id); + stop_cheat_caller_address(channel_contract_address); + + start_cheat_caller_address(channel_contract_address, MEMBER2.try_into().unwrap()); + dispatcher.leave_channel(channel_id); stop_cheat_caller_address(channel_contract_address); } +