Files
self/contracts/test/integration/verifyAll.test.ts
Nesopie e77247f372 Feat/kyc (#1623)
* feat: selfrica circuit and tests

* chore: remove unused code

* feat: test for ofac,date and olderthan

* fix: public signal constant

* feat: add contract tests

* feat: helper function to gen TEE input

* feat: gen circuit inputs with signature

* feat: seralized base64

* fix: DateIsLessFullYear componenet

* feat: register circuit for selfrica

* feat: selfrica disclose circuit and test

* fix: common module error

* feat: add more test and fix constant

* fix: commitment calculation

* feat: selfrica contracts

* test: selfrica register using unified circuit

* feat: register persona and selfrica circuit

* feat: selfrica circuit and tests

* chore: remove unused code

* feat: test for ofac,date and olderthan

* fix: public signal constant

* feat: add contract tests

* feat: helper function to gen TEE input

* feat: gen circuit inputs with signature

* feat: seralized base64

* fix: DateIsLessFullYear componenet

* feat: register circuit for selfrica

* feat: selfrica disclose circuit and test

* fix: common module error

* feat: add more test and fix constant

* fix: commitment calculation

* feat: selfrica contracts

* test: selfrica register using unified circuit

* feat: register persona and selfrica circuit

* refactor: contract size reduction for IdentityVerificationHubImplV2

export function logic to external libs, reduce compiler runs to 200, update deploy scripts to link new libs

* feat: disclose circuit for persona

* feat: update  persona ofac trees

* feat; register circuit for selfper

* feat: disclose test for selfper

* chore: refactor

* chore : remove unused circuits

* chore: rename selfper to kyc

* chore: update comments

* feat: constrain s to be 251 bit

* feat: add range check on majority ASCII and comments

* feat: range check on neg_r_inv

* chore: remove is pk zero constrain

* merge dev

* feat: add registerPubkey function to Selfrica with GCPJWT Verification

* test: add testing for GCPJWT verification on Selfrica

* fix: script that calls register_selfrica circuits (ptau:14 -> ptau:15)

* fix: get remaining Selfrica tests working with proper import paths

* refactor: store pubkeys as string

also add some comment code for registerPubkey function

* refactor: remove registerPubkeyCommitment function

some tests now skipped as awaiting changes to how pubkeys are stored (string instead of uint256)

* feat: use hex decoding for the pubkey commitment

* test: adjust tests for pubkey being string again

* fix: remove old references to registerPubkey

* docs: add full natspec for IdentityRegistrySelfricaImplV1

* docs: update files in rest of the repo for Selfrica attestation type

* test: fix broken tests

* fix: builds and move to kyc from selfrica

* fix: constrain r_inv, Rx, s, T

* feat: eddsa

* feat: add onlyTEE check to registerPubkeyCommitment

onlyOwner is able to change onlyTEE

* refactor: update gcpRootCAPubkeyHash to be changeable by owner

* feat: add events for update functions

* style: move functions to be near other similar functions

* fix: kyc happy flow

* fix: all contract tests passing

| fix: timestamp conversion with Date(), migrate to V2 for endToEnd test, scope formatting, fix register aadhaar issue by using block.timestamp instead of Date.now(), fix changed getter function name, enable MockGCPJWTVerifier with updated file paths, add missing LeanIMT import, fix user identifier format

* audit: bind key offset-value offset and ensure image_digest only occurs once in the payload

* fix: constrain bracket

* chore: update comment

* audit: hardcode attestation id

* audit: make sure R and pubkey are on the curve

* audit: ensure pubkey is within bounds

* fix: all contract tests passing

* feat: change max length to 99 from 74

* audit: don't check sha256 padding

* audit: check the last window as well

* audit: single occurance for eat_nonce and image_digest

* audit: check if the certs are expired

* audit: add the timestamp check to the contract

* audit: make sure the person is less than 255 years of age

* audit fixes

* chore: yarn.lock

* fix: build fixes

* fix: aadhaar timestamp

* lint

* fix: types

* format

---------

Co-authored-by: vishal <vishalkoolkarni0045@gmail.com>
Co-authored-by: Evi Nova <tranquil_flow@protonmail.com>
2026-01-19 15:54:37 +05:30

525 lines
20 KiB
TypeScript

import { expect } from "chai";
import { ethers } from "hardhat";
import { deploySystemFixtures } from "../utils/deployment";
import { DeployedActors, VcAndDiscloseHubProof } from "../utils/types";
import { generateRandomFieldElement, splitHexFromBack } from "../utils/utils";
import { generateCommitment } from "@selfxyz/common/utils/passports/passport";
import { ATTESTATION_ID } from "../utils/constants";
import { CIRCUIT_CONSTANTS } from "@selfxyz/common/constants/constants";
import { poseidon2 } from "poseidon-lite";
import { generateVcAndDiscloseProof, parseSolidityCalldata } from "../utils/generateProof";
import { Formatter } from "../utils/formatter";
import { formatCountriesList, reverseBytes } from "@selfxyz/common/utils/circuits/formatInputs";
import { stringToBigInt } from "@selfxyz/common/utils/scope";
import { VerifyAll } from "../../typechain-types";
import { getSMTs } from "../utils/generateProof";
import { Groth16Proof, PublicSignals, groth16 } from "snarkjs";
import { VcAndDiscloseProof } from "../utils/types";
import { stringToBigInt } from "@selfxyz/common/utils/scope";
describe("VerifyAll", () => {
let deployedActors: DeployedActors;
let verifyAll: VerifyAll;
let snapshotId: string;
let baseVcAndDiscloseProof: any;
let vcAndDiscloseProof: any;
let registerSecret: any;
let imt: any;
let commitment: any;
let nullifier: any;
let forbiddenCountriesList: string[];
let invalidForbiddenCountriesList: string[];
let forbiddenCountriesListPacked: string[];
let invalidForbiddenCountriesListPacked: string[];
before(async () => {
deployedActors = await deploySystemFixtures();
const VerifyAllFactory = await ethers.getContractFactory("VerifyAll");
verifyAll = await VerifyAllFactory.deploy(deployedActors.hub.getAddress(), deployedActors.registry.getAddress());
registerSecret = generateRandomFieldElement();
nullifier = generateRandomFieldElement();
commitment = generateCommitment(registerSecret, ATTESTATION_ID.E_PASSPORT, deployedActors.mockPassport);
const hashFunction = (a: bigint, b: bigint) => poseidon2([a, b]);
// must be imported dynamic since @openpassport/zk-kit-lean-imt is exclusively esm and hardhat does not support esm with typescript until verison 3
const LeanIMT = await import("@openpassport/zk-kit-lean-imt").then((mod) => mod.LeanIMT);
imt = new LeanIMT<bigint>(hashFunction);
await imt.insert(BigInt(commitment));
forbiddenCountriesList = [
"AAA",
"ABC",
"CBA",
"AAA",
"AAA",
"ABC",
"CBA",
"AAA",
"ABC",
"CBA",
"AAA",
"ABC",
"CBA",
"AAA",
"ABC",
"CBA",
"AAA",
"ABC",
"CBA",
"AAA",
"ABC",
"CBA",
"AAA",
"ABC",
"CBA",
"AAA",
"ABC",
"CBA",
"AAA",
"ABC",
"CBA",
"AAA",
"ABC",
"CBA",
"AAA",
"ABC",
"CBA",
"AAA",
"ABC",
"CBA",
];
const wholePacked = reverseBytes(
Formatter.bytesToHexString(new Uint8Array(formatCountriesList(forbiddenCountriesList))),
);
forbiddenCountriesListPacked = splitHexFromBack(wholePacked);
invalidForbiddenCountriesList = ["AAA", "ABC", "CBA", "CBA"];
const invalidWholePacked = reverseBytes(
Formatter.bytesToHexString(new Uint8Array(formatCountriesList(invalidForbiddenCountriesList))),
);
invalidForbiddenCountriesListPacked = splitHexFromBack(invalidWholePacked);
baseVcAndDiscloseProof = await generateVcAndDiscloseProof(
registerSecret,
BigInt(ATTESTATION_ID.E_PASSPORT).toString(),
deployedActors.mockPassport,
stringToBigInt("test-scope").toString(),
new Array(88).fill("1"),
"1",
imt,
"20",
undefined,
undefined,
undefined,
undefined,
forbiddenCountriesList,
await deployedActors.user1.getAddress(),
);
snapshotId = await ethers.provider.send("evm_snapshot", []);
});
beforeEach(async () => {
vcAndDiscloseProof = structuredClone(baseVcAndDiscloseProof);
});
afterEach(async () => {
await ethers.provider.send("evm_revert", [snapshotId]);
snapshotId = await ethers.provider.send("evm_snapshot", []);
});
describe("verifyAll", () => {
it("should verify and get result successfully", async () => {
const { registry, owner } = deployedActors;
const tx = await registry
.connect(owner)
.devAddIdentityCommitment(ATTESTATION_ID.E_PASSPORT, nullifier, commitment);
const receipt = (await tx.wait()) as any;
const timestamp = (await ethers.provider.getBlock(receipt.blockNumber))!.timestamp;
const vcAndDiscloseHubProof: VcAndDiscloseHubProof = {
olderThanEnabled: true,
olderThan: "20",
forbiddenCountriesEnabled: true,
forbiddenCountriesListPacked: forbiddenCountriesListPacked,
ofacEnabled: [true, true, true],
vcAndDiscloseProof: vcAndDiscloseProof,
};
const types = ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10"]; // Example types
const [readableData, success] = await verifyAll.verifyAll(timestamp, vcAndDiscloseHubProof, types);
expect(success).to.be.true;
expect(readableData.name).to.not.be.empty;
});
it("should verify and get result successfully with out timestamp verification", async () => {
const { registry, owner } = deployedActors;
await registry.connect(owner).devAddIdentityCommitment(ATTESTATION_ID.E_PASSPORT, nullifier, commitment);
const vcAndDiscloseHubProof: VcAndDiscloseHubProof = {
olderThanEnabled: true,
olderThan: "20",
forbiddenCountriesEnabled: true,
forbiddenCountriesListPacked: forbiddenCountriesListPacked,
ofacEnabled: [true, true, true],
vcAndDiscloseProof: vcAndDiscloseProof,
};
const types = ["0", "1", "2"]; // Example types
const [readableData, success] = await verifyAll.verifyAll(0, vcAndDiscloseHubProof, types);
expect(success).to.be.true;
expect(readableData.name).to.not.be.empty;
});
it("should return empty result when verification fails", async () => {
const { registry, owner } = deployedActors;
await registry.connect(owner).devAddIdentityCommitment(ATTESTATION_ID.E_PASSPORT, nullifier, commitment);
vcAndDiscloseProof.pubSignals[CIRCUIT_CONSTANTS.VC_AND_DISCLOSE_MERKLE_ROOT_INDEX] = generateRandomFieldElement();
const vcAndDiscloseHubProof: VcAndDiscloseHubProof = {
olderThanEnabled: true,
olderThan: "20",
forbiddenCountriesEnabled: true,
forbiddenCountriesListPacked: forbiddenCountriesListPacked,
ofacEnabled: [true, true, true],
vcAndDiscloseProof: vcAndDiscloseProof,
};
const types = ["0", "1", "2"];
const [readableData, success] = await verifyAll.verifyAll(0, vcAndDiscloseHubProof, types);
expect(success).to.be.false;
expect(readableData.name).to.be.empty;
});
it("should fail with invalid root timestamp", async () => {
const { registry, owner } = deployedActors;
await registry.connect(owner).devAddIdentityCommitment(ATTESTATION_ID.E_PASSPORT, nullifier, commitment);
const vcAndDiscloseHubProof: VcAndDiscloseHubProof = {
olderThanEnabled: true,
olderThan: "20",
forbiddenCountriesEnabled: true,
forbiddenCountriesListPacked: forbiddenCountriesListPacked,
ofacEnabled: [true, true, true],
vcAndDiscloseProof: vcAndDiscloseProof,
};
const types = ["0", "1", "2"];
const [readableData, success] = await verifyAll.verifyAll(123456, vcAndDiscloseHubProof, types);
expect(success).to.be.false;
expect(readableData.name).to.be.empty;
});
describe("Error Handling", () => {
it("should return error code 'INVALID_VC_AND_DISCLOSE_PROOF' when proof is invalid", async () => {
const { registry, owner } = deployedActors;
await registry.connect(owner).devAddIdentityCommitment(ATTESTATION_ID.E_PASSPORT, nullifier, commitment);
vcAndDiscloseProof.a[0] = generateRandomFieldElement();
const vcAndDiscloseHubProof: VcAndDiscloseHubProof = {
olderThanEnabled: false,
olderThan: "20",
forbiddenCountriesEnabled: false,
forbiddenCountriesListPacked: forbiddenCountriesListPacked,
ofacEnabled: [false, false, false],
vcAndDiscloseProof: vcAndDiscloseProof,
};
const types = ["0", "1", "2"];
const [readableData, success, errorCode] = await verifyAll.verifyAll(0, vcAndDiscloseHubProof, types);
expect(success).to.be.false;
expect(errorCode).to.equal("INVALID_VC_AND_DISCLOSE_PROOF");
expect(readableData.name).to.be.empty;
});
it("should return error code 'CURRENT_DATE_NOT_IN_VALID_RANGE' when date is invalid", async () => {
const { registry, owner } = deployedActors;
await registry.connect(owner).devAddIdentityCommitment(ATTESTATION_ID.E_PASSPORT, nullifier, commitment);
vcAndDiscloseProof.pubSignals[CIRCUIT_CONSTANTS.VC_AND_DISCLOSE_CURRENT_DATE_INDEX] = 0;
const vcAndDiscloseHubProof: VcAndDiscloseHubProof = {
olderThanEnabled: true,
olderThan: "20",
forbiddenCountriesEnabled: true,
forbiddenCountriesListPacked: forbiddenCountriesListPacked,
ofacEnabled: [true, true, true],
vcAndDiscloseProof: vcAndDiscloseProof,
};
const types = ["0", "1", "2"];
const [readableData, success, errorCode] = await verifyAll.verifyAll(0, vcAndDiscloseHubProof, types);
expect(success).to.be.false;
expect(errorCode).to.equal("CURRENT_DATE_NOT_IN_VALID_RANGE");
expect(readableData.name).to.be.empty;
});
it("should return error code 'INVALID_OLDER_THAN' when age check fails", async () => {
const { registry, owner } = deployedActors;
await registry.connect(owner).devAddIdentityCommitment(ATTESTATION_ID.E_PASSPORT, nullifier, commitment);
const vcAndDiscloseHubProof: VcAndDiscloseHubProof = {
olderThanEnabled: true,
olderThan: "21", // Higher than the age in proof
forbiddenCountriesEnabled: false,
forbiddenCountriesListPacked: forbiddenCountriesListPacked,
ofacEnabled: [false, false, false],
vcAndDiscloseProof: vcAndDiscloseProof,
};
const types = ["0", "1", "2"];
const [readableData, success, errorCode] = await verifyAll.verifyAll(0, vcAndDiscloseHubProof, types);
expect(success).to.be.false;
expect(errorCode).to.equal("INVALID_OLDER_THAN");
expect(readableData.name).to.be.empty;
});
it("should return error code 'INVALID_OFAC' when OFAC check fails", async () => {
const { registry, owner } = deployedActors;
await registry.connect(owner).devAddIdentityCommitment(ATTESTATION_ID.E_PASSPORT, nullifier, commitment);
const { passportNo_smt, nameAndDob_smt, nameAndYob_smt } = getSMTs();
vcAndDiscloseProof = await generateVcAndDiscloseProof(
registerSecret,
BigInt(ATTESTATION_ID.E_PASSPORT).toString(),
deployedActors.mockPassport,
stringToBigInt("test-scope").toString(),
new Array(88).fill("1"),
"1",
imt,
"20",
passportNo_smt,
nameAndDob_smt,
nameAndYob_smt,
"0",
);
const vcAndDiscloseHubProof: VcAndDiscloseHubProof = {
olderThanEnabled: true,
olderThan: "20",
forbiddenCountriesEnabled: false,
forbiddenCountriesListPacked: forbiddenCountriesListPacked,
ofacEnabled: [true, true, true],
vcAndDiscloseProof: vcAndDiscloseProof,
};
const types = ["0", "1", "2"];
const [readableData, success, errorCode] = await verifyAll.verifyAll(0, vcAndDiscloseHubProof, types);
console.log("return values");
console.log("readable data: ", readableData);
console.log("success: ", success);
console.log("errorCode: ", errorCode);
expect(success).to.be.false;
expect(errorCode).to.equal("INVALID_OFAC");
expect(readableData.name).to.be.empty;
});
it("should return error code 'INVALID_FORBIDDEN_COUNTRIES' when countries check fails", async () => {
const { registry, owner } = deployedActors;
await registry.connect(owner).devAddIdentityCommitment(ATTESTATION_ID.E_PASSPORT, nullifier, commitment);
const vcAndDiscloseHubProof: VcAndDiscloseHubProof = {
olderThanEnabled: true,
olderThan: "20",
forbiddenCountriesEnabled: true,
forbiddenCountriesListPacked: invalidForbiddenCountriesListPacked,
ofacEnabled: [true, true, true],
vcAndDiscloseProof: vcAndDiscloseProof,
};
const types = ["0", "1", "2"];
const [readableData, success, errorCode] = await verifyAll.verifyAll(0, vcAndDiscloseHubProof, types);
expect(success).to.be.false;
expect(errorCode).to.equal("INVALID_FORBIDDEN_COUNTRIES");
expect(readableData.name).to.be.empty;
});
it("should return error code 'INVALID_TIMESTAMP' when root timestamp doesn't match", async () => {
const { registry, owner } = deployedActors;
await registry.connect(owner).devAddIdentityCommitment(ATTESTATION_ID.E_PASSPORT, nullifier, commitment);
const vcAndDiscloseHubProof: VcAndDiscloseHubProof = {
olderThanEnabled: true,
olderThan: "20",
forbiddenCountriesEnabled: true,
forbiddenCountriesListPacked: forbiddenCountriesListPacked,
ofacEnabled: [true, true, true],
vcAndDiscloseProof: vcAndDiscloseProof,
};
const types = ["0", "1", "2"];
const [readableData, success, errorCode] = await verifyAll.verifyAll(
123456, // Invalid timestamp
vcAndDiscloseHubProof,
types,
);
expect(success).to.be.false;
expect(errorCode).to.equal("INVALID_TIMESTAMP");
expect(readableData.name).to.be.empty;
});
it("should return error code 'INVALID_OFAC_ROOT' when passport number OFAC root is invalid", async () => {
const { registry, owner } = deployedActors;
await registry.connect(owner).devAddIdentityCommitment(ATTESTATION_ID.E_PASSPORT, nullifier, commitment);
vcAndDiscloseProof.pubSignals[CIRCUIT_CONSTANTS.VC_AND_DISCLOSE_PASSPORT_NO_SMT_ROOT_INDEX] =
generateRandomFieldElement();
const vcAndDiscloseHubProof: VcAndDiscloseHubProof = {
olderThanEnabled: true,
olderThan: "20",
forbiddenCountriesEnabled: true,
forbiddenCountriesListPacked: forbiddenCountriesListPacked,
ofacEnabled: [true, true, true],
vcAndDiscloseProof: vcAndDiscloseProof,
};
const types = ["0", "1", "2"];
const [readableData, success, errorCode] = await verifyAll.verifyAll(0, vcAndDiscloseHubProof, types);
expect(success).to.be.false;
expect(errorCode).to.equal("INVALID_OFAC_ROOT");
expect(readableData.name).to.be.empty;
});
it("should return error code 'INVALID_OFAC_ROOT' when name and dob OFAC root is invalid", async () => {
const { registry, owner } = deployedActors;
await registry.connect(owner).devAddIdentityCommitment(ATTESTATION_ID.E_PASSPORT, nullifier, commitment);
vcAndDiscloseProof.pubSignals[CIRCUIT_CONSTANTS.VC_AND_DISCLOSE_NAME_DOB_SMT_ROOT_INDEX] =
generateRandomFieldElement();
const vcAndDiscloseHubProof: VcAndDiscloseHubProof = {
olderThanEnabled: true,
olderThan: "20",
forbiddenCountriesEnabled: true,
forbiddenCountriesListPacked: forbiddenCountriesListPacked,
ofacEnabled: [false, true, false],
vcAndDiscloseProof: vcAndDiscloseProof,
};
const types = ["0", "1", "2"];
const [readableData, success, errorCode] = await verifyAll.verifyAll(0, vcAndDiscloseHubProof, types);
expect(success).to.be.false;
expect(errorCode).to.equal("INVALID_OFAC_ROOT");
expect(readableData.name).to.be.empty;
});
it("should return error code 'INVALID_OFAC_ROOT' when name and yob OFAC root is invalid", async () => {
const { registry, owner } = deployedActors;
await registry.connect(owner).devAddIdentityCommitment(ATTESTATION_ID.E_PASSPORT, nullifier, commitment);
vcAndDiscloseProof.pubSignals[CIRCUIT_CONSTANTS.VC_AND_DISCLOSE_NAME_YOB_SMT_ROOT_INDEX] =
generateRandomFieldElement();
const vcAndDiscloseHubProof: VcAndDiscloseHubProof = {
olderThanEnabled: true,
olderThan: "20",
forbiddenCountriesEnabled: true,
forbiddenCountriesListPacked: forbiddenCountriesListPacked,
ofacEnabled: [false, false, true],
vcAndDiscloseProof: vcAndDiscloseProof,
};
const types = ["0", "1", "2"];
const [readableData, success, errorCode] = await verifyAll.verifyAll(0, vcAndDiscloseHubProof, types);
expect(success).to.be.false;
expect(errorCode).to.equal("INVALID_OFAC_ROOT");
expect(readableData.name).to.be.empty;
});
});
});
describe("admin functions", () => {
it("should allow owner to set new hub address", async () => {
const newHubAddress = await deployedActors.user1.getAddress();
await verifyAll.setHub(newHubAddress);
});
it("should allow owner to set new registry address", async () => {
const newRegistryAddress = await deployedActors.user1.getAddress();
await verifyAll.setRegistry(newRegistryAddress);
});
it("should not allow non-owner to set new hub address", async () => {
const newHubAddress = await deployedActors.user1.getAddress();
await expect(verifyAll.connect(deployedActors.user1).setHub(newHubAddress)).to.be.revertedWithCustomError(
verifyAll,
"AccessControlUnauthorizedAccount",
);
});
it("should not allow non-owner to set new registry address", async () => {
const newRegistryAddress = await deployedActors.user1.getAddress();
await expect(
verifyAll.connect(deployedActors.user1).setRegistry(newRegistryAddress),
).to.be.revertedWithCustomError(verifyAll, "AccessControlUnauthorizedAccount");
});
});
describe("VerifyAll (Custom Error Handling)", () => {
it("should return error code 'INVALID_VC_AND_DISCLOSE_PROOF' when vcAndDisclose proof is invalid", async () => {
const { registry, owner } = deployedActors;
await registry.connect(owner).devAddIdentityCommitment(ATTESTATION_ID.E_PASSPORT, nullifier, commitment);
vcAndDiscloseProof.a[0] = generateRandomFieldElement();
const vcAndDiscloseHubProof: VcAndDiscloseHubProof = {
olderThanEnabled: true,
olderThan: "20",
forbiddenCountriesEnabled: true,
forbiddenCountriesListPacked: forbiddenCountriesListPacked,
ofacEnabled: [true, true, true],
vcAndDiscloseProof: vcAndDiscloseProof,
};
const types = ["0", "1", "2"];
const [readableData, success, errorCode] = await verifyAll.verifyAll(0, vcAndDiscloseHubProof, types);
expect(success).to.be.false;
expect(errorCode).to.equal("INVALID_VC_AND_DISCLOSE_PROOF");
expect(readableData.name).to.be.empty;
});
it("should return error code 'CURRENT_DATE_NOT_IN_VALID_RANGE' when current date is out of range", async () => {
const { registry, owner } = deployedActors;
await registry.connect(owner).devAddIdentityCommitment(ATTESTATION_ID.E_PASSPORT, nullifier, commitment);
vcAndDiscloseProof.pubSignals[CIRCUIT_CONSTANTS.VC_AND_DISCLOSE_CURRENT_DATE_INDEX] = 0;
const vcAndDiscloseHubProof: VcAndDiscloseHubProof = {
olderThanEnabled: true,
olderThan: "20",
forbiddenCountriesEnabled: true,
forbiddenCountriesListPacked: forbiddenCountriesListPacked,
ofacEnabled: [true, true, true],
vcAndDiscloseProof: vcAndDiscloseProof,
};
const types = ["0", "1", "2"];
const [readableData, success, errorCode] = await verifyAll.verifyAll(0, vcAndDiscloseHubProof, types);
expect(success).to.be.false;
expect(errorCode).to.equal("CURRENT_DATE_NOT_IN_VALID_RANGE");
expect(readableData.name).to.be.empty;
});
});
});