Initiatives: add addressForNodeEntry (#1758)

Defines the NodeAddress format we want to use for a NodeEntry.

Because we want to use the parent InitiativeId as parts of the address,
we'll need to read the underlying string[], changing the opaque type.
This commit is contained in:
Robin van Boven 2020-04-27 18:15:18 +02:00 committed by GitHub
parent 203b48066c
commit 5ef69bef50
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 52 additions and 1 deletions

View File

@ -7,7 +7,7 @@ import {type TimestampMs} from "../../util/timestamp";
import {initiativeNodeType} from "./declaration";
// Composite ID, used as input for NodeAddressT.
export opaque type InitiativeId = string[];
export opaque type InitiativeId: string[] = string[];
// Enforce that each ID has at least a sub-type and 1..n components.
export function createId(

View File

@ -2,8 +2,11 @@
import {type URL} from "../../core/references";
import {type NodeWeight} from "../../core/weights";
import {type NodeAddressT, NodeAddress} from "../../core/graph";
import {type TimestampMs, type TimestampISO} from "../../util/timestamp";
import * as Timestamp from "../../util/timestamp";
import {type InitiativeId} from "./initiative";
import {nodeEntryTypes} from "./declaration";
/**
* Represents an "inline contribution" node. They're called entries and named
@ -47,6 +50,14 @@ export type NodeEntryJson = $Shape<{
+weight: NodeWeight | null,
}>;
export function addressForNodeEntry(
field: NodeEntryField,
id: InitiativeId,
key: string
): NodeAddressT {
return NodeAddress.append(nodeEntryTypes[field].prefix, ...id, key);
}
/**
* Takes a NodeEntryJson and normalizes it to a NodeEntry.
*

View File

@ -2,14 +2,54 @@
import {type TimestampMs} from "../../util/timestamp";
import * as Timestamp from "../../util/timestamp";
import {NodeAddress} from "../../core/graph";
import {createId} from "./initiative";
import {
type NodeEntry,
type NodeEntryJson,
addressForNodeEntry,
normalizeNodeEntry,
_titleSlug,
} from "./nodeEntry";
describe("plugins/initiatives/nodeEntry", () => {
describe("addressForNodeEntry", () => {
it("should handle each field value as a different node type", () => {
const id = createId("EXAMPLE", "123");
const addresses = [
addressForNodeEntry("DEPENDENCY", id, "some-dependency-key"),
addressForNodeEntry("REFERENCE", id, "some-reference-key"),
addressForNodeEntry("CONTRIBUTION", id, "contrib-key"),
];
expect(addresses).toEqual([
NodeAddress.fromParts([
"sourcecred",
"initiatives",
"DEPENDENCY",
"EXAMPLE",
"123",
"some-dependency-key",
]),
NodeAddress.fromParts([
"sourcecred",
"initiatives",
"REFERENCE",
"EXAMPLE",
"123",
"some-reference-key",
]),
NodeAddress.fromParts([
"sourcecred",
"initiatives",
"CONTRIBUTION",
"EXAMPLE",
"123",
"contrib-key",
]),
]);
});
});
describe("normalizeNodeEntry", () => {
it("should throw without a title", () => {
const timestampMs: TimestampMs = Timestamp.fromNumber(123);