Skip to content

Commit

Permalink
Join all Get Started code blocks in a single test
Browse files Browse the repository at this point in the history
Joining all the example code blocks present in Get Started section of
documentation makes the tests easier to understand, less redundant and
have a more logical flow since all code shown on Get Started is part of
a tutorial code and not isolated chunks of code.
  • Loading branch information
manumonti committed Jan 11, 2023
1 parent 987f9c2 commit ea360dc
Show file tree
Hide file tree
Showing 2 changed files with 89 additions and 45 deletions.
126 changes: 82 additions & 44 deletions test/docs/cbd.test.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { VerifiedKeyFrag } from '@nucypher/nucypher-core';
import { providers } from 'ethers';

import {
Expand All @@ -7,9 +8,16 @@ import {
SecretKey,
Strategy,
} from '../../src';
import { Ursula } from '../../src/characters/porter';
import { toBytes } from '../../src/utils';
import {
mockDetectEthereumProvider,
mockEncryptTreasureMap,
mockGenerateKFrags,
mockGetUrsulas,
mockMakeTreasureMap,
mockPublishToBlockchain,
mockRetrieveCFragsRequest,
mockUrsulas,
mockWeb3Provider,
} from '../utils';
Expand All @@ -27,27 +35,30 @@ describe('Get Started (CBD PoC)', () => {
jest.unmock('ethers');
});

it('2. Build a Cohort', async () => {
const mockedUrsulas = mockUrsulas().slice(0, 3);
it('can run the get started example', async () => {
const mockedUrsulas = mockUrsulas();
const getUrsulasSpy = mockGetUrsulas(mockedUrsulas);
const generateKFragsSpy = mockGenerateKFrags();
const publishToBlockchainSpy = mockPublishToBlockchain();
const makeTreasureMapSpy = mockMakeTreasureMap();
const encryptTreasureMapSpy = mockEncryptTreasureMap();
const detectEthereumProvider = mockDetectEthereumProvider();

// Start of the code example
// Start of 2. Build a Cohort
const config = {
threshold: 3,
shares: 5,
porterUri: 'https://porter-tapir.nucypher.community',
};
const newCohort = await Cohort.create(config);
// End of the example code
// End of 2. Build a Cohort

expect(getUrsulasSpy).toHaveBeenCalled();
const expectedAddresses = mockedUrsulas.map((u) => u.checksumAddress);
expect(newCohort.ursulaAddresses).toEqual(expectedAddresses);
expect(getUrsulasSpy).toHaveBeenCalled();
expect(newCohort.configuration).toEqual(config);
});

it('3. Specify default Conditions', () => {
// Start of the code example
// Start of 3. Specify default Conditions
const NFTOwnership = new Conditions.ERC721Ownership({
contractAddress: '0xBC4CA0EdA7647A8aB7C2061c2E118A18a936f13D',
chain: 5, // Tapir network uses Görli testnet
Expand All @@ -58,56 +69,83 @@ describe('Get Started (CBD PoC)', () => {
NFTOwnership,
// Other conditions can be added here
]);
// End of the example code
// End of 3. Specify default Conditions

const condObj = conditions.conditions[0].toObj();
expect(conditions.validate()).toEqual(true);
expect(condObj).toEqual(NFTOwnership.toObj());
expect(condObj.parameters).toEqual([5954]);
expect(condObj.chain).toEqual(5);
expect(condObj.contractAddress).toEqual(
'0xBC4CA0EdA7647A8aB7C2061c2E118A18a936f13D'
);
});

it('4. Build a Strategy', async () => {
const mockedUrsulas = mockUrsulas().slice(0, 3);
mockGetUrsulas(mockedUrsulas);
const publishToBlockchainSpy = mockPublishToBlockchain();
expect(conditions.validate()).toEqual(true);

const cohortConfig = {
threshold: 2,
shares: 3,
porterUri: 'https://_this.should.crash',
};
const newCohort = await Cohort.create(cohortConfig);
// Start of 4. Build a Strategy
const newStrategy = Strategy.create(newCohort, conditions);

const NFTOwnership = new Conditions.ERC721Ownership({
contractAddress: '0xBC4CA0EdA7647A8aB7C2061c2E118A18a936f13D',
chain: 5, // Tapir network uses Görli testnet
parameters: [5954],
});

const conditions = new ConditionSet([NFTOwnership]);
const MMprovider = await detectEthereumProvider();
const mumbai = providers.getNetwork(80001);

const strategy = Strategy.create(newCohort, conditions);
if (MMprovider) {
const web3Provider = new providers.Web3Provider(MMprovider, mumbai);
const newDeployed = await newStrategy.deploy('test', web3Provider);
// End of 4. Build a Strategy

expect(publishToBlockchainSpy).toHaveBeenCalled();
expect(newDeployed.label).toEqual('test');

// Start of 5. Encrypt the plaintext & update Conditions
const NFTBalanceConfig = {
contractAddress: '0xBC4CA0EdA7647A8aB7C2061c2E118A18a936f13D',
standardContractType: 'ERC721',
chain: 5,
method: 'balanceOf',
parameters: [':userAddress'],
returnValueTest: {
comparator: '>=',
value: 3,
},
};
const NFTBalance = new Conditions.Condition(NFTBalanceConfig);

const encrypter = newDeployed.encrypter;

const plaintext = 'this is a secret';
const encryptedMessageKit = encrypter.encryptMessage(
plaintext,
new ConditionSet([NFTBalance])
);
// End of 5. Encrypt the plaintext & update Conditions

expect(getUrsulasSpy).toHaveBeenCalledTimes(2);
expect(generateKFragsSpy).toHaveBeenCalled();
expect(encryptTreasureMapSpy).toHaveBeenCalled();
expect(makeTreasureMapSpy).toHaveBeenCalled();

// Setup mocks for `retrieveAndDecrypt`
const ursulaAddresses = (
makeTreasureMapSpy.mock.calls[0][0] as readonly Ursula[]
).map((u) => u.checksumAddress);
const verifiedKFrags = makeTreasureMapSpy.mock
.calls[0][1] as readonly VerifiedKeyFrag[];
const retrieveCFragsSpy = mockRetrieveCFragsRequest(
ursulaAddresses,
verifiedKFrags,
encryptedMessageKit.capsule
);

const detectEthereumProvider = jest.fn(async () => {
return {} as unknown as providers.ExternalProvider;
});
// Start of 6. Request decryption rights
const decrypter = newDeployed.decrypter;

const ethProvider = await detectEthereumProvider();
const mumbai = providers.getNetwork(80001);
const conditionContext = conditions.buildContext(web3Provider);
const decryptedMessage = await decrypter.retrieveAndDecrypt(
[encryptedMessageKit],
conditionContext
);
// End of 6. Request decryption rights

if (ethProvider) {
const web3Provider = new providers.Web3Provider(ethProvider, mumbai);
const deployedStrategy = await strategy.deploy('test', web3Provider);
console.log(deployedStrategy);
expect(retrieveCFragsSpy).toHaveBeenCalled();
expect(decryptedMessage[0]).toEqual(toBytes(plaintext));
}

// End of the code example
const expectedAddresses = mockedUrsulas.map((u) => u.checksumAddress);
expect(newCohort.ursulaAddresses).toEqual(expectedAddresses);
expect(publishToBlockchainSpy).toHaveBeenCalled();
});
});
8 changes: 7 additions & 1 deletion test/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import {
VerifiedKeyFrag,
} from '@nucypher/nucypher-core';
import axios from 'axios';
import { ethers, Wallet } from 'ethers';
import { ethers, providers, Wallet } from 'ethers';

import { Alice, Bob, Configuration, RemoteBob } from '../src';
import {
Expand Down Expand Up @@ -210,3 +210,9 @@ export const reencryptKFrags = (
export const mockMakeTreasureMap = () => {
return jest.spyOn(BlockchainPolicy.prototype as any, 'makeTreasureMap');
};

export const mockDetectEthereumProvider = () => {
return jest.fn(async () => {
return {} as unknown as providers.ExternalProvider;
});
};

0 comments on commit ea360dc

Please sign in to comment.