UNPKG

@ssb-graphql/whakapapa

Version:

GraphQL types and resolvers for the ssb-whakapapa plugin

295 lines (258 loc) 7.9 kB
const test = require('tape') const { promisify: p } = require('util') const TestBot = require('../test-bot') const CHILD = 'link/profile-profile/child' const PARTNER = 'link/profile-profile/partner' const compare = (a, b) => { return (a.parent + a.child).localeCompare(b.parent + b.child) } test('loadFamilyOfPerson', async t => { const { ssb, apollo } = await TestBot({ loadContext: true }) const { groupId } = await p(ssb.tribes.create)({}) const content = (opts = {}) => ({ ...opts, authors: { add: [ssb.id] }, recps: [groupId] }) // A has partners: // - X their ex! // - B their current partner // A has children: // - ax // - ab // B has another child: // - bc (with parent C) // X has another child: // - xy (with parent Y - relationshipType: null) // // Like so: // // Y X A---B C // \ / \ / | \ / // xy ax ab bc // TODO - also queue up partners as other people to explore const [A, B, C, X, Y, ax, ab, bc, xy] = await Promise.all( new Array(9).fill(0) .map(() => p(ssb.profile.person.group.create)(content())) ) const details = { recps: [groupId] } await p(ssb.whakapapa.link.create)({ type: PARTNER, parent: B, child: A }, details) // TODO add relationshipType to partners then enable this // await p(ssb.whakapapa.link.create)({ type: PARTNER, parent: A, child: B, relationshipType: 'divorced' }) const childLinks = await Promise.all([ { parent: A, child: ax }, // 0 { parent: A, child: ax }, // 1 deliberate duplicate { parent: A, child: ab }, // 2 { parent: B, child: ab }, // 3 { parent: B, child: bc }, // 4 { parent: C, child: bc }, // 5 { parent: X, child: xy }, // 6 { parent: X, child: ax }, // 7 { parent: Y, child: xy } // 8 ].map(link => p(ssb.whakapapa.link.create)({ type: CHILD, ...link }, details) )) // console.timeEnd('setup relationships') const linkAax = childLinks[0] const linkXax = childLinks[7] const QUERY = `query ($profileId: String!, $extended: Boolean) { loadFamilyOfPerson(id: $profileId, extended: $extended) { childLinks { parent child relationshipType } partnerLinks { parent child relationshipType } } }` let result // shallow result = await apollo.query({ query: QUERY, variables: { profileId: A // extended: false } }).catch(err => { throw err }) let actual = result.data.loadFamilyOfPerson let expected = { childLinks: [ { parent: A, child: ax, relationshipType: null }, { parent: A, child: ab, relationshipType: null } ], partnerLinks: [ { parent: B, child: A, relationshipType: 'partners' } ] } t.deepEqual(actual, expected, 'simple family') // if A-ax + X-ax are birth relationships, we infer another (ex) partner await p(ssb.whakapapa.link.update)(linkAax, { relationshipType: 'birth' }) await p(ssb.whakapapa.link.update)(linkXax, { relationshipType: 'birth' }) result = await apollo.query({ query: QUERY, variables: { profileId: A // extended: false } }).catch(err => { throw err }) actual = result.data.loadFamilyOfPerson expected = { childLinks: [ { parent: A, child: ax, relationshipType: 'birth' }, { parent: A, child: ab, relationshipType: null }, { parent: X, child: ax, relationshipType: 'birth' } ], partnerLinks: [ { parent: B, child: A, relationshipType: 'partners' }, inferredPartnerLink(A, X) ] } t.deepEqual( actual.childLinks.sort(compare), expected.childLinks.sort(compare), 'an ex-partner you had a child with' ) t.deepEqual( actual.partnerLinks.sort(compare), expected.partnerLinks.sort(compare), 'an ex-partner you had a child with' ) ssb.close() t.end() }) test('loadFamilyOfPerson (extended: true)', async t => { const { ssb, apollo } = await TestBot({ loadContext: true }) const { groupId } = await p(ssb.tribes.create)({}) const content = (opts = {}) => ({ ...opts, authors: { add: [ssb.id] }, recps: [groupId] }) // A has partners: // - X their ex! // - B their current partner // A has children: // - ax // - ab // B has another child: // - bc (with parent C) // X has another child: // - xy (with parent Y) // // Like so: // // Y X A---B C // \ / \ / | \ / // xy ax ab bc // ssb.post(m => ssb.get({ id: m.key, private: true }, (err, val) => console.log(val.content))) const [A, B, C, X, Y, ax, ab, bc, xy] = await Promise.all( new Array(9).fill(0) .map(() => p(ssb.profile.person.group.create)(content())) ) const details = { recps: [groupId] } await p(ssb.whakapapa.link.create)({ type: PARTNER, parent: A, child: B }, details) // TODO add relationshipType to partners then enable this // await p(ssb.whakapapa.link.create)({ type: PARTNER, parent: A, child: B, relationshipType: 'divorced' }) details.relationshipType = 'birth' await Promise.all([ { parent: A, child: ax }, // 0 { parent: A, child: ax }, // 1 deliberate duplicate { parent: A, child: ab }, // 2 { parent: B, child: ab }, // 3 { parent: B, child: bc }, // 4 { parent: C, child: bc }, // 5 { parent: X, child: xy }, // 6 { parent: X, child: ax } // 7 // { parent: Y, child: xy } // 8 ].map(link => p(ssb.whakapapa.link.create)({ type: CHILD, ...link }, details) )) // NOTE one link of relationshipType: null await p(ssb.whakapapa.link.create)({ type: CHILD, parent: Y, child: xy }, { recps: [groupId] }) // 8 const QUERY = `query ($profileId: String!, $extended: Boolean) { loadFamilyOfPerson(id: $profileId, extended: $extended) { childLinks { parent child relationshipType } partnerLinks { parent child relationshipType } } }` // extended const result = await apollo.query({ query: QUERY, variables: { profileId: A, extended: true } }).catch(err => { throw err }) t.deepEqual( result.data.loadFamilyOfPerson.childLinks.sort(compare), [ { parent: A, child: ax, relationshipType: 'birth' }, // 0 { parent: A, child: ab, relationshipType: 'birth' }, // 1 { parent: X, child: ax, relationshipType: 'birth' }, // 7 { parent: B, child: ab, relationshipType: 'birth' }, // 3 { parent: B, child: bc, relationshipType: 'birth' }, // 4 { parent: C, child: bc, relationshipType: 'birth' }, // 5 { parent: X, child: xy, relationshipType: 'birth' }, // 6 { parent: Y, child: xy, relationshipType: null } // 8 ].sort(compare), 'childLinks ok' ) t.deepEqual( result.data.loadFamilyOfPerson.partnerLinks.sort(compare), [ { parent: A, child: B, relationshipType: 'partners' }, inferredPartnerLink(A, X), inferredPartnerLink(B, C) // inferredPartnerLink(X, Y) // Y-xy = not birth relationship ].sort(compare), 'partnerLinks ok' ) /* A function that's useful for debugging function prettyPrint (label, links) { const map = { [A]: 'A', [B]: 'B', [C]: 'C', [X]: 'X', [Y]: 'Y', [ab]: 'ab', [ax]: 'ax', [bc]: 'bc', [xy]: 'xy' } const decode = (link) => ({ ...link, parent: map[link.parent], child: map[link.child] }) console.log( label, JSON.stringify( links.sort(compare).map(decode), null, 2 ) ) } */ ssb.close() t.end() }) function inferredPartnerLink (a, b) { const [parent, child] = [a, b].sort() return { parent, child, relationshipType: 'inferred' } // this is how the fns builds the inferred links, // so we emulate this here for predictable tests }