119 lines
		
	
	
		
			5.7 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
			
		
		
	
	
			119 lines
		
	
	
		
			5.7 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
| import { blockchainTests, constants, expect, randomAddress, verifyEventsFromLogs } from '@0x/contracts-test-utils';
 | |
| import { hexUtils, OwnableRevertErrors, ZeroExRevertErrors } from '@0x/utils';
 | |
| 
 | |
| import { artifacts } from '../artifacts';
 | |
| import { basicMigrateAsync } from '../utils/migration';
 | |
| import {
 | |
|     ISimpleFunctionRegistryContract,
 | |
|     ISimpleFunctionRegistryEvents,
 | |
|     ITestSimpleFunctionRegistryFeatureContract,
 | |
|     TestSimpleFunctionRegistryFeatureImpl1Contract,
 | |
|     TestSimpleFunctionRegistryFeatureImpl2Contract,
 | |
| } from '../wrappers';
 | |
| 
 | |
| blockchainTests.resets('SimpleFunctionRegistry feature', env => {
 | |
|     const { NULL_ADDRESS } = constants;
 | |
|     const notOwner = randomAddress();
 | |
|     let owner: string;
 | |
|     let registry: ISimpleFunctionRegistryContract;
 | |
|     let testFnSelector: string;
 | |
|     let testFeature: ITestSimpleFunctionRegistryFeatureContract;
 | |
|     let testFeatureImpl1: TestSimpleFunctionRegistryFeatureImpl1Contract;
 | |
|     let testFeatureImpl2: TestSimpleFunctionRegistryFeatureImpl2Contract;
 | |
| 
 | |
|     before(async () => {
 | |
|         [owner] = await env.getAccountAddressesAsync();
 | |
|         const zeroEx = await basicMigrateAsync(owner, env.provider, env.txDefaults);
 | |
|         registry = new ISimpleFunctionRegistryContract(zeroEx.address, env.provider, {
 | |
|             ...env.txDefaults,
 | |
|             from: owner,
 | |
|         });
 | |
|         testFeature = new ITestSimpleFunctionRegistryFeatureContract(zeroEx.address, env.provider, env.txDefaults);
 | |
|         testFnSelector = testFeature.getSelector('testFn');
 | |
|         testFeatureImpl1 = await TestSimpleFunctionRegistryFeatureImpl1Contract.deployFrom0xArtifactAsync(
 | |
|             artifacts.TestSimpleFunctionRegistryFeatureImpl1,
 | |
|             env.provider,
 | |
|             env.txDefaults,
 | |
|             artifacts,
 | |
|         );
 | |
|         testFeatureImpl2 = await TestSimpleFunctionRegistryFeatureImpl2Contract.deployFrom0xArtifactAsync(
 | |
|             artifacts.TestSimpleFunctionRegistryFeatureImpl2,
 | |
|             env.provider,
 | |
|             env.txDefaults,
 | |
|             artifacts,
 | |
|         );
 | |
|     });
 | |
| 
 | |
|     it('`extend()` cannot be called by a non-owner', async () => {
 | |
|         const tx = registry.extend(hexUtils.random(4), randomAddress()).callAsync({ from: notOwner });
 | |
|         return expect(tx).to.revertWith(new OwnableRevertErrors.OnlyOwnerError(notOwner, owner));
 | |
|     });
 | |
| 
 | |
|     it('`rollback()` cannot be called by a non-owner', async () => {
 | |
|         const tx = registry.rollback(hexUtils.random(4)).callAsync({ from: notOwner });
 | |
|         return expect(tx).to.revertWith(new OwnableRevertErrors.OnlyOwnerError(notOwner, owner));
 | |
|     });
 | |
| 
 | |
|     it('`rollback()` reverts for unregistered function', async () => {
 | |
|         const tx = registry.rollback(testFnSelector).awaitTransactionSuccessAsync();
 | |
|         return expect(tx).to.revertWith(
 | |
|             new ZeroExRevertErrors.SimpleFunctionRegistry.NoRollbackHistoryError(testFnSelector),
 | |
|         );
 | |
|     });
 | |
| 
 | |
|     it('owner can add a new function with `extend()`', async () => {
 | |
|         const { logs } = await registry.extend(testFnSelector, testFeatureImpl1.address).awaitTransactionSuccessAsync();
 | |
|         verifyEventsFromLogs(
 | |
|             logs,
 | |
|             [{ selector: testFnSelector, oldImpl: NULL_ADDRESS, newImpl: testFeatureImpl1.address }],
 | |
|             ISimpleFunctionRegistryEvents.ProxyFunctionUpdated,
 | |
|         );
 | |
|         const r = await testFeature.testFn().callAsync();
 | |
|         expect(r).to.bignumber.eq(1337);
 | |
|     });
 | |
| 
 | |
|     it('owner can replace add a function with `extend()`', async () => {
 | |
|         await registry.extend(testFnSelector, testFeatureImpl1.address).awaitTransactionSuccessAsync();
 | |
|         await registry.extend(testFnSelector, testFeatureImpl2.address).awaitTransactionSuccessAsync();
 | |
|         const r = await testFeature.testFn().callAsync();
 | |
|         expect(r).to.bignumber.eq(1338);
 | |
|     });
 | |
| 
 | |
|     it('owner can unset a function with `extend()`', async () => {
 | |
|         await registry.extend(testFnSelector, testFeatureImpl1.address).awaitTransactionSuccessAsync();
 | |
|         await registry.extend(testFnSelector, constants.NULL_ADDRESS).awaitTransactionSuccessAsync();
 | |
|         return expect(testFeature.testFn().callAsync()).to.revertWith(
 | |
|             new ZeroExRevertErrors.Proxy.NotImplementedError(testFnSelector),
 | |
|         );
 | |
|     });
 | |
| 
 | |
|     it('owner can rollback a new function to unset', async () => {
 | |
|         await registry.extend(testFnSelector, testFeatureImpl1.address).awaitTransactionSuccessAsync();
 | |
|         const { logs } = await registry.rollback(testFnSelector).awaitTransactionSuccessAsync();
 | |
|         verifyEventsFromLogs(
 | |
|             logs,
 | |
|             [{ selector: testFnSelector, oldImpl: testFeatureImpl1.address, newImpl: NULL_ADDRESS }],
 | |
|             ISimpleFunctionRegistryEvents.ProxyFunctionUpdated,
 | |
|         );
 | |
|         return expect(testFeature.testFn().callAsync()).to.revertWith(
 | |
|             new ZeroExRevertErrors.Proxy.NotImplementedError(testFnSelector),
 | |
|         );
 | |
|     });
 | |
| 
 | |
|     it('owner can rollback a function to a previous version', async () => {
 | |
|         await registry.extend(testFnSelector, testFeatureImpl1.address).awaitTransactionSuccessAsync();
 | |
|         await registry.extend(testFnSelector, testFeatureImpl2.address).awaitTransactionSuccessAsync();
 | |
|         await registry.rollback(testFnSelector).awaitTransactionSuccessAsync();
 | |
|         const r = await testFeature.testFn().callAsync();
 | |
|         expect(r).to.bignumber.eq(1337);
 | |
|     });
 | |
| 
 | |
|     it('owner can rollback an unset function to a previous version', async () => {
 | |
|         await registry.extend(testFnSelector, testFeatureImpl1.address).awaitTransactionSuccessAsync();
 | |
|         await registry.extend(testFnSelector, constants.NULL_ADDRESS).awaitTransactionSuccessAsync();
 | |
|         await registry.rollback(testFnSelector).awaitTransactionSuccessAsync();
 | |
|         const r = await testFeature.testFn().callAsync();
 | |
|         expect(r).to.bignumber.eq(1337);
 | |
|     });
 | |
| });
 |