From 8eb93122773ea21009c92306636417f181a4cc56 Mon Sep 17 00:00:00 2001 From: Robin van Boven <497556+Beanow@users.noreply.github.com> Date: Sat, 8 Feb 2020 08:46:32 +0100 Subject: [PATCH] Initiatives: create InitiativeId concept (#1646) Previously we were relying on the `Initiative.tracker` to define the address of an Initiative. Based on feedback at #1643 we want to remove trackers. So we'll need a replacement ID. This will enforce a new InitiativeId convention. As well as how to derive a NodeAddressT from it. In a follow-up we'll remove the tracker concept. --- src/plugins/initiatives/initiative.js | 19 ++++++++- src/plugins/initiatives/initiative.test.js | 49 ++++++++++++++++++++++ 2 files changed, 67 insertions(+), 1 deletion(-) create mode 100644 src/plugins/initiatives/initiative.test.js diff --git a/src/plugins/initiatives/initiative.js b/src/plugins/initiatives/initiative.js index c5294bc..4737a3d 100644 --- a/src/plugins/initiatives/initiative.js +++ b/src/plugins/initiatives/initiative.js @@ -1,9 +1,26 @@ // @flow -import {type NodeAddressT} from "../../core/graph"; +import {type NodeAddressT, NodeAddress} from "../../core/graph"; +import {initiativeNodeType} from "./declaration"; export type URL = string; +// Composite ID, used as input for NodeAddressT. +export opaque type InitiativeId = string[]; + +// Enforce that each ID has at least a sub-type and 1..n components. +export function createId( + subType: string, + requiredId: string, + ...rest: string[] +): InitiativeId { + return [subType, requiredId, ...rest]; +} + +export function addressFromId(id: InitiativeId): NodeAddressT { + return NodeAddress.append(initiativeNodeType.prefix, ...id); +} + /** * An intermediate representation of an Initiative. * diff --git a/src/plugins/initiatives/initiative.test.js b/src/plugins/initiatives/initiative.test.js new file mode 100644 index 0000000..3c3b7a5 --- /dev/null +++ b/src/plugins/initiatives/initiative.test.js @@ -0,0 +1,49 @@ +// @flow + +import {NodeAddress} from "../../core/graph"; +import {createId, addressFromId} from "./initiative"; + +describe("plugins/initiatives/initiative", () => { + describe("createId", () => { + it("should require a subtype as first argument", () => { + // $ExpectFlowError + createId(); + }); + + it("should require at least one ID component as second argument", () => { + // $ExpectFlowError + createId("SUBTYPE"); + }); + + it("should work given at least a subtype and one ID component", () => { + const id = createId("SUBTYPE", "123"); + expect(id).toEqual(["SUBTYPE", "123"]); + }); + + it("should work with an arbitrary number of ID components", () => { + const id = createId("SUBTYPE", "123", "456", "789"); + expect(id).toEqual(["SUBTYPE", "123", "456", "789"]); + }); + }); + + describe("addressFromId", () => { + it("should add the correct prefix to an InitiativeId", () => { + // Given + const id = createId("EXAMPLE", "123"); + + // When + const address = addressFromId(id); + + // Then + expect(address).toEqual( + NodeAddress.fromParts([ + "sourcecred", + "initiatives", + "initiative", + "EXAMPLE", + "123", + ]) + ); + }); + }); +});