~ knotless Search/
↑↓ move↵ open⇧↵ all results

chadtmiller.com/pds.js

An atproto PDS in JavaScript, for Cloudflare Workers and Node

0
0
main
263 lines · 7.4 KB Raw History
/**
 * Matching commit authors against the identities an account claims.
 */

import { describe, expect, it } from 'vitest';
import {
  coAuthorsOf,
  creditAuthors,
  identMatches,
  matchIdent,
  parseIdentityRecord,
  splitIdent,
} from '../src/authors.js';

describe('splitIdent', () => {
  it('separates the name from the address', () => {
    expect(splitIdent('Chad Miller <chad@example.com>')).toEqual({
      name: 'Chad Miller',
      email: 'chad@example.com',
    });
  });

  it('reads an ident that carries no address', () => {
    expect(splitIdent('Chad Miller')).toEqual({
      name: 'Chad Miller',
      email: '',
    });
  });

  it('reads an address with no name, as git writes for an empty user.name', () => {
    expect(splitIdent('<chad@example.com>')).toEqual({
      name: '',
      email: 'chad@example.com',
    });
  });

  it('handles an angle bracket inside the name', () => {
    expect(splitIdent('a <b> c <real@example.com>')).toEqual({
      name: 'a <b> c',
      email: 'real@example.com',
    });
  });
});

describe('parseIdentityRecord', () => {
  it('lowercases addresses and drops malformed entries', () => {
    expect(
      parseIdentityRecord({
        idents: [
          { email: '  Chad@Example.COM ' },
          { name: 'Chad Miller' },
          { email: 42 },
          {},
          null,
          'nope',
        ],
      }),
    ).toEqual([
      {
        name: '',
        email: 'chad@example.com',
        did: '',
        label: '',
        avatarCid: '',
      },
      { name: 'Chad Miller', email: '', did: '', label: '', avatarCid: '' },
    ]);
  });

  it('keeps a did that names somebody other than the account', () => {
    expect(
      parseIdentityRecord({
        idents: [
          { email: 'them@example.com', did: 'did:plc:someone' },
          { email: 'bogus@example.com', did: 'not-a-did' },
        ],
      }),
    ).toEqual([
      {
        name: '',
        email: 'them@example.com',
        did: 'did:plc:someone',
        label: '',
        avatarCid: '',
      },
      {
        name: '',
        email: 'bogus@example.com',
        did: '',
        label: '',
        avatarCid: '',
      },
    ]);
  });

  it('carries the label and face of an identity with no account', () => {
    expect(
      parseIdentityRecord({
        idents: [
          {
            email: 'noreply@anthropic.com',
            label: 'Claude',
            avatar: { $type: 'blob', ref: { $link: 'bafyface' } },
          },
        ],
      }),
    ).toEqual([
      {
        name: '',
        email: 'noreply@anthropic.com',
        did: '',
        label: 'Claude',
        avatarCid: 'bafyface',
      },
    ]);
  });

  it('reads a record with no idents as no claims', () => {
    expect(parseIdentityRecord({})).toEqual([]);
    expect(parseIdentityRecord(null)).toEqual([]);
    expect(parseIdentityRecord({ idents: 'nope' })).toEqual([]);
  });
});

describe('identMatches', () => {
  const claims = parseIdentityRecord({
    idents: [{ email: 'chad@example.com' }, { name: 'Solo Name' }],
  });

  it('matches an address whatever name it travels under', () => {
    expect(identMatches(claims, 'Chad Miller <chad@example.com>')).toBe(true);
    expect(identMatches(claims, 'Someone Else <CHAD@EXAMPLE.COM>')).toBe(true);
  });

  it('does not match an address that was never claimed', () => {
    expect(identMatches(claims, 'Chad Miller <other@example.com>')).toBe(false);
  });

  it('matches a name-only claim against a commit with no address', () => {
    expect(identMatches(claims, 'Solo Name')).toBe(true);
  });

  it('never lets a name-only claim capture a commit that names an address', () => {
    // Otherwise claiming a common name would take over every commit that
    // author name appears on, whoever actually wrote it.
    expect(identMatches(claims, 'Solo Name <someone@example.com>')).toBe(false);
  });

  it('matches nothing when the account claims nothing', () => {
    expect(identMatches([], 'Chad Miller <chad@example.com>')).toBe(false);
  });

  it('returns the matched claim, so a reader can see whose identity it is', () => {
    const vouched = parseIdentityRecord({
      idents: [{ email: 'them@example.com', did: 'did:plc:someone' }],
    });
    expect(matchIdent(vouched, 'Them <them@example.com>')?.did).toBe(
      'did:plc:someone',
    );
    expect(matchIdent(vouched, 'Other <other@example.com>')).toBeNull();
  });

  it('prefers an address claim over a name claim for the same commit', () => {
    // Otherwise a bare-name claim listed first would answer for a commit the
    // address claim identifies exactly.
    const both = parseIdentityRecord({
      idents: [
        { name: 'Chad Miller' },
        { email: 'chad@example.com', did: 'did:plc:byaddress' },
      ],
    });
    expect(matchIdent(both, 'Chad Miller <chad@example.com>')?.did).toBe(
      'did:plc:byaddress',
    );
  });
});

describe('coAuthorsOf', () => {
  it('reads the trailers a message ends with', () => {
    expect(
      coAuthorsOf(
        'feat: a thing\n\nWhy it is here.\n\n' +
          'Co-Authored-By: Ada <ada@example.com>\n' +
          'Co-authored-by: Bo <bo@example.com>\n',
      ),
    ).toEqual(['Ada <ada@example.com>', 'Bo <bo@example.com>']);
  });

  it('credits each person once, however often they are named', () => {
    expect(
      coAuthorsOf(
        'x\n\nCo-authored-by: Ada <ada@example.com>\n' +
          'Co-authored-by: ada <ADA@example.com>\n',
      ),
    ).toEqual(['Ada <ada@example.com>']);
  });

  it('reads only the last paragraph, so a quoted trailer credits nobody', () => {
    expect(
      coAuthorsOf(
        'revert\n\nThis reverts a commit that said:\n' +
          'Co-authored-by: Ada <ada@example.com>\n\n' +
          'Co-authored-by: Bo <bo@example.com>\n',
      ),
    ).toEqual(['Bo <bo@example.com>']);
  });

  it('answers empty for a message with no trailers', () => {
    expect(coAuthorsOf('just a subject')).toEqual([]);
    expect(coAuthorsOf('')).toEqual([]);
  });
});

describe('creditAuthors', () => {
  /** @param {string} author @param {string} [message] */
  const commit = (author, message = 'x') => ({ author, message });

  it('holds one row for the names one address writes', () => {
    expect(
      creditAuthors([
        commit('Ada Lovelace <ada@example.com>'),
        commit('ada <ADA@example.com>'),
        commit('A. Lovelace <ada@example.com>'),
      ]),
    ).toEqual([{ ident: 'Ada Lovelace <ada@example.com>', commits: 3 }]);
  });

  it('credits the people a message names beside the author', () => {
    expect(
      creditAuthors([
        commit(
          'Ada <ada@example.com>',
          'a\n\nCo-authored-by: Bo <bo@example.com>\n',
        ),
        commit('Ada <ada@example.com>'),
      ]),
    ).toEqual([
      { ident: 'Ada <ada@example.com>', commits: 2 },
      { ident: 'Bo <bo@example.com>', commits: 1 },
    ]);
  });

  it('credits an author their own message names once', () => {
    expect(
      creditAuthors([
        commit(
          'Ada <ada@example.com>',
          'a\n\nCo-authored-by: Ada Lovelace <ada@example.com>\n',
        ),
      ]),
    ).toEqual([{ ident: 'Ada <ada@example.com>', commits: 1 }]);
  });

  it('keys an ident with no address on its name', () => {
    expect(creditAuthors([commit('Ada'), commit('ada')])).toEqual([
      { ident: 'Ada', commits: 2 },
    ]);
  });

  it('answers empty for no commits', () => {
    expect(creditAuthors([])).toEqual([]);
  });
});