Skip to content

Commit

Permalink
Migrate Upgrades tests (#1051)
Browse files Browse the repository at this point in the history
* Migrate Upgrades tests to Foundry

* Update src/tests/upgrades/test_upgradeable.cairo

Co-authored-by: Andrew Fleming <[email protected]>

* Update src/tests/upgrades/test_upgradeable.cairo

Co-authored-by: Andrew Fleming <[email protected]>

---------

Co-authored-by: Eric Nordelo <[email protected]>
Co-authored-by: Andrew Fleming <[email protected]>
  • Loading branch information
3 people authored Jul 17, 2024
1 parent 8fe4f80 commit 6f7130f
Show file tree
Hide file tree
Showing 4 changed files with 48 additions and 41 deletions.
4 changes: 2 additions & 2 deletions src/tests.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ mod mocks;
mod security;
#[cfg(test)]
mod token;
// #[cfg(test)]
// mod upgrades;
#[cfg(test)]
mod upgrades;

pub mod utils;
24 changes: 14 additions & 10 deletions src/tests/upgrades/common.cairo
Original file line number Diff line number Diff line change
@@ -1,16 +1,20 @@
use openzeppelin::tests::utils::constants::ZERO;
use openzeppelin::tests::utils;
use openzeppelin::tests::utils::events::EventSpyExt;
use openzeppelin::upgrades::UpgradeableComponent::Upgraded;
use openzeppelin::upgrades::UpgradeableComponent;
use snforge_std::{EventSpy, EventSpyAssertionsTrait};
use starknet::{ContractAddress, ClassHash};

pub(crate) fn assert_event_upgraded(contract: ContractAddress, class_hash: ClassHash) {
let event = utils::pop_log::<UpgradeableComponent::Event>(contract).unwrap();
let expected = UpgradeableComponent::Event::Upgraded(Upgraded { class_hash });
assert!(event == expected);
}
#[generate_trait]
pub(crate) impl UpgradableSpyHelpersImpl of UpgradableSpyHelpers {
fn assert_event_upgraded(ref self: EventSpy, contract: ContractAddress, class_hash: ClassHash) {
let expected = UpgradeableComponent::Event::Upgraded(Upgraded { class_hash });
self.assert_emitted_single(contract, expected);
}

pub(crate) fn assert_only_event_upgraded(contract: ContractAddress, class_hash: ClassHash) {
assert_event_upgraded(contract, class_hash);
utils::assert_no_events_left(ZERO());
fn assert_only_event_upgraded(
ref self: EventSpy, contract: ContractAddress, class_hash: ClassHash
) {
self.assert_event_upgraded(contract, class_hash);
self.assert_no_events_left_from(contract);
}
}
60 changes: 31 additions & 29 deletions src/tests/upgrades/test_upgradeable.cairo
Original file line number Diff line number Diff line change
@@ -1,56 +1,54 @@
use openzeppelin::tests::mocks::upgrades_mocks::{
IUpgradesV1Dispatcher, IUpgradesV1DispatcherTrait, UpgradesV1
};
use openzeppelin::tests::mocks::upgrades_mocks::{
IUpgradesV2Dispatcher, IUpgradesV2DispatcherTrait, UpgradesV2
};
use openzeppelin::tests::utils::constants::{CLASS_HASH_ZERO, ZERO};
use openzeppelin::tests::utils;
use openzeppelin::tests::mocks::upgrades_mocks::{IUpgradesV2Dispatcher, IUpgradesV2DispatcherTrait};
use openzeppelin::tests::utils::common::{declare_class, deploy};
use openzeppelin::tests::utils::constants::{CLASS_HASH_ZERO, ZERO, FELT_VALUE as VALUE};
use openzeppelin::tests::utils::events::EventSpyExt;
use openzeppelin::upgrades::UpgradeableComponent;
use starknet::ClassHash;

use super::common::assert_only_event_upgraded;
use snforge_std::ContractClass;
use snforge_std::{spy_events, EventSpy};

const VALUE: felt252 = 123;

fn V2_CLASS_HASH() -> ClassHash {
UpgradesV2::TEST_CLASS_HASH.try_into().unwrap()
}
use super::common::UpgradableSpyHelpers;

//
// Setup
//

fn deploy_v1() -> IUpgradesV1Dispatcher {
let calldata = array![];
let address = utils::deploy(UpgradesV1::TEST_CLASS_HASH, calldata);
IUpgradesV1Dispatcher { contract_address: address }
fn setup_test() -> (IUpgradesV1Dispatcher, ContractClass, ContractClass) {
let v1_class = declare_class("UpgradesV1");
let v2_class = declare_class("UpgradesV2");
let v1_contract_address = deploy(v1_class, array![]);
let v1 = IUpgradesV1Dispatcher { contract_address: v1_contract_address };
(v1, v1_class, v2_class)
}

//
// upgrade
//

#[test]
#[should_panic(expected: ('Class hash cannot be zero', 'ENTRYPOINT_FAILED',))]
#[should_panic(expected: ('Class hash cannot be zero',))]
fn test_upgrade_with_class_hash_zero() {
let v1 = deploy_v1();
let (v1, _v1_class, _v2_class) = setup_test();
v1.upgrade(CLASS_HASH_ZERO());
}

#[test]
fn test_upgraded_event() {
let v1 = deploy_v1();
v1.upgrade(V2_CLASS_HASH());
let (v1, _v1_class, v2_class) = setup_test();
let mut spy = spy_events();

assert_only_event_upgraded(v1.contract_address, V2_CLASS_HASH());
v1.upgrade(v2_class.class_hash);

spy.assert_only_event_upgraded(v1.contract_address, v2_class.class_hash);
}

#[test]
fn test_new_selector_after_upgrade() {
let v1 = deploy_v1();
let (v1, _v1_class, v2_class) = setup_test();

v1.upgrade(V2_CLASS_HASH());
v1.upgrade(v2_class.class_hash);
let v2 = IUpgradesV2Dispatcher { contract_address: v1.contract_address };

v2.set_value2(VALUE);
Expand All @@ -59,26 +57,30 @@ fn test_new_selector_after_upgrade() {

#[test]
fn test_state_persists_after_upgrade() {
let v1 = deploy_v1();
let (v1, _v1_class, v2_class) = setup_test();

v1.set_value(VALUE);

v1.upgrade(V2_CLASS_HASH());
v1.upgrade(v2_class.class_hash);
let v2 = IUpgradesV2Dispatcher { contract_address: v1.contract_address };

assert_eq!(v2.get_value(), VALUE);
}

#[test]
fn test_remove_selector_passes_in_v1() {
let v1 = deploy_v1();
let (v1, _v1_class, _v2_class) = setup_test();

v1.remove_selector();
}

#[test]
#[ignore] // REASON: inconsistent ENTRYPOINT_NOT_FOUND panic message
#[should_panic(expected: ('ENTRYPOINT_NOT_FOUND',))]
fn test_remove_selector_fails_in_v2() {
let v1 = deploy_v1();
v1.upgrade(V2_CLASS_HASH());
let (v1, _v1_class, v2_class) = setup_test();

v1.upgrade(v2_class.class_hash);
// We use the v1 dispatcher because remove_selector is not in v2 interface
v1.remove_selector();
}
1 change: 1 addition & 0 deletions src/tests/utils/constants.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ use starknet::secp256_trait::Secp256Trait;
pub(crate) const DECIMALS: u8 = 18_u8;
pub(crate) const SUPPLY: u256 = 2000;
pub(crate) const VALUE: u256 = 300;
pub(crate) const FELT_VALUE: felt252 = 'FELT_VALUE';
pub(crate) const ROLE: felt252 = 'ROLE';
pub(crate) const OTHER_ROLE: felt252 = 'OTHER_ROLE';
pub(crate) const TOKEN_ID: u256 = 21;
Expand Down

0 comments on commit 6f7130f

Please sign in to comment.