# How Automated Tests Validate is-a.dev Domain Configurations

> Learn how automated tests validate is-a.dev domain configurations for syntax, hierarchy, ownership, and policy compliance using the AVA test framework in the is-a-dev register repository.

- Repository: [is-a.dev/register](https://github.com/is-a-dev/register)
- Tags: how-to-guide
- Published: 2026-03-09

---

**The is-a.dev registry uses the AVA test framework to automatically validate every domain JSON file for syntax correctness, hierarchical integrity, ownership consistency, and policy compliance on every pull request.**

The **is-a-dev/register** repository manages thousands of sub-domain configurations stored as individual JSON files. To maintain DNS integrity and enforce strict registration policies, the project implements a comprehensive automated testing suite that executes via GitHub Actions. These automated tests for is-a.dev domain configurations verify everything from JSON syntax to parent-child domain relationships before any change reaches the production DNS infrastructure.

## Test Framework and Execution Environment

The test suite runs on **AVA**, a fast, minimal test runner that executes each test in its own process to ensure isolation. The entry point resides in the `tests/` directory and is invoked through the `npm test` script defined in **package.json**, which declares AVA as a devDependency.

When a contributor opens a pull request, GitHub Actions automatically triggers the full test suite. A single failing assertion blocks the merge, ensuring that every submitted domain configuration obeys the registry’s strict policy set before DNS publication.

## Domain Integrity and Hierarchy Validation

The **tests/domains.test.js** file enforces structural rules that prevent DNS delegation conflicts and ownership disputes. It validates cross-file relationships using a caching mechanism that loads each JSON file once via `fs.readJsonSync` for repeated lookups during the test run.

### File Discovery and Parent-Child Relationships

The test runner first gathers all configuration files using a strict filter to ensure only JSON data is processed:

```javascript
const domainsPath = path.resolve("domains");
const files = fs.readdirSync(domainsPath).filter(file => file.endsWith(".json"));

```

For every nested sub-domain, the tests verify that a parent JSON file exists, unless the parent is a special wildcard record beginning with "_". The validation splits the sub-domain into parts and walks up the hierarchy:

```javascript
files.forEach(file => {
  const subdomain = file.replace(/\.json$/, "");
  const parts = subdomain.split(".");
  for (let i = 1; i < parts.length; i++) {
    const parent = parts.slice(i).join(".");
    if (parent.startsWith("_")) continue;
    t.true(files.includes(`${parent}.json`),
      `${file}: Parent subdomain "${parent}" does not exist`);
  }
});

```

### NS Record and Ownership Constraints

The tests prevent delegation conflicts by checking that **no parent domain holding NS records can have children**. The suite loads the parent data via `getDomainData` and asserts `!parentData.records.NS` to block incompatible configurations.

**Ownership inheritance** is strictly enforced: a child domain’s `owner.username` must match its parent’s owner. The test compares `data.owner.username` with `parentData.owner.username` to prevent unauthorized sub-domain takeovers.

### Single-Character and Reserved Name Restrictions

Only the `is-a-dev` organization may register single-character sub-domains. The test filters sub-domains of length 1 and asserts the owner field equals `is-a-dev`. Additionally, the suite blocks registration of names listed in **util/internal.json** and **util/reserved.json** by asserting `t.false(internalDomains.includes(subdomain))`.

## JSON Syntax and Schema Enforcement

The **tests/json.test.js** file handles syntactic validation and schema compliance, ensuring every file is parseable and conforms to the expected data structure.

### Duplicate Key Detection

To prevent silent configuration overrides, the tests implement a custom `findDuplicateKeys` parser that scans raw JSON strings for repeated keys at any nesting level:

```javascript
function findDuplicateKeys(jsonString) {
  const duplicateKeys = new Set();
  const keyStack = [];
  const keyRegex = /"(.*?)"\s*:/g;
  let i = 0;
  while (i < jsonString.length) {
    const char = jsonString[i];
    if (char === "{") { keyStack.push({}); i++; continue; }
    if (char === "}") { keyStack.pop(); i++; continue; }
    keyRegex.lastIndex = i;
    const match = keyRegex.exec(jsonString);
    if (match && match.index === i && keyStack.length > 0) {
      const key = match[1];
      const currentScope = keyStack[keyStack.length - 1];
      if (currentScope[key]) duplicateKeys.add(key);
      else currentScope[key] = true;
      i = keyRegex.lastIndex;
    } else { i++; }
  }
  return [...duplicateKeys];
}

```

### Required Fields and Type Validation

The `validateFields` function walks schema definitions to check that mandatory objects like `owner` and `records` exist and that optional fields respect their declared types:

```javascript
const requiredFields = { owner: "object", records: "object" };

async function validateFields(t, obj, fields, file, prefix = "") {
  for (const key of Object.keys(fields)) {
    const fieldPath = prefix ? `${prefix}.${key}` : key;
    if (obj.hasOwnProperty(key)) {
      t.is(typeof obj[key], fields[key],
        `${file}: Field ${fieldPath} should be of type ${fields[key]}`);
    } else {
      t.true(false, `${file}: Missing required field: ${fieldPath}`);
    }
  }
}

```

### File Naming and Blocked Fields

The `validateFileName` function enforces strict naming conventions: files must be lower-case, end with `.json`, avoid consecutive hyphens, and match `hostnameRegex`. The suite also prohibits blocked fields like `domain`, `internal`, and `proxy` by looping over `blockedFields` and asserting `!data.hasOwnProperty(field)`.

## CI/CD Integration and Merge Protection

All validation logic executes automatically in GitHub Actions whenever code is pushed to a pull request. The workflow runs `npm test`, which invokes AVA against both **domains.test.js** and **json.test.js**. Because the suite touches every domain file in the `domains/` directory, it serves as an exhaustive guardrail for the entire registry.

The **dnsconfig.js** module, which reads these JSON files to generate the actual DNS zone, relies on this test suite to ensure its inputs are valid, indirectly protecting the production DNS infrastructure from misconfigurations.

## Summary

- **AVA Test Runner**: Executes isolated tests via `npm test` in the **is-a-dev/register** repository.
- **Domain Hierarchy Checks**: Validates parent-child relationships, NS record conflicts, and ownership inheritance in **tests/domains.test.js**.
- **Schema Validation**: Enforces JSON syntax, required fields, and type checking through **tests/json.test.js**.
- **Naming Policies**: Blocks reserved names, single-character domains (except for `is-a-dev`), and invalid file formats.
- **Merge Blocking**: GitHub Actions runs all tests on every PR, preventing invalid configurations from reaching production DNS.

## Frequently Asked Questions

### What testing framework does is-a.dev use for domain validation?

The project uses **AVA**, a minimal JavaScript test runner configured in **package.json** as a devDependency. AVA executes each test file in a separate process, providing isolation for the thousands of domain configuration checks.

### How does the test suite verify parent-child domain relationships?

The tests in **tests/domains.test.js** split each sub-domain into parts and verify that every parent level has a corresponding JSON file in the `domains/` directory, unless the parent starts with "_". This ensures DNS delegation chains remain unbroken and prevents orphaned sub-domains.

### Can a domain file contain duplicate JSON keys?

No. The **json.test.js** file implements a custom `findDuplicateKeys` function that parses the raw JSON string to detect duplicate keys at any nesting level. Files with duplicate keys fail the test suite immediately, preventing silent configuration overrides.

### Who is allowed to register single-character sub-domains?

Only the `is-a-dev` organization may own single-character sub-domains. The test suite explicitly filters for domain names of length 1 and asserts that the `owner.username` field equals `is-a-dev`, reserving these scarce resources for official project use.