| … | … | @@ -0,0 +1,70 @@ |
| 1 | import test from 'brittle' |
| 2 | import Corestore from 'corestore' |
| 3 | import { mkdtempSync } from 'fs' |
| 4 | import { join } from 'path' |
| 5 | import { tmpdir } from 'os' |
| 6 | import { replicateAndSync } from 'autobase-test-helpers' |
| 7 | import { HyperOrgs } from '../index.js' |
| 8 | import { HyperIssues, issuesSchema } from 'hyper-issues' |
| 9 | |
| 10 | function tmp () { return mkdtempSync(join(tmpdir(), 'orgs-issues-')) } |
| 11 | |
| 12 | // #42 fix, proven at the library layer. |
| 13 | // |
| 14 | // An org Room built with composeSchemas([orgsSchema, issuesSchema]) |
| 15 | // carries its issues IN the org's own autobase. So a peer that joins |
| 16 | // ONLY the org's record autobase (peer mode — mountOrg) also gets its |
| 17 | // issues, with NO separate tracker autobase and NO issueBootstrapKey |
| 18 | // conveyance. This is the linked-core (Keet db+blobs) shape. |
| 19 | test('org issues live in the org room and replicate WITH the org', async (t) => { |
| 20 | const owner = new HyperOrgs(new Corestore(tmp()), { |
| 21 | namespace: 'owner', extraSchemas: [issuesSchema] |
| 22 | }) |
| 23 | await owner.ready() |
| 24 | await owner.create('alpha', 'group', { displayName: 'Alpha' }) |
| 25 | |
| 26 | const ownerRoom = owner.getOrgRoom('alpha') |
| 27 | const ownerIssues = new HyperIssues(null, { room: ownerRoom, ownsRoom: false }) |
| 28 | await ownerIssues.ready() |
| 29 | const id = await ownerIssues.create({ title: 'org issue', body: 'b', author: 'owner' }) |
| 30 | |
| 31 | // Peer mounts ONLY alpha's record autobase (peer mode). |
| 32 | const peer = new HyperOrgs(new Corestore(tmp()), { |
| 33 | namespace: 'peer', extraSchemas: [issuesSchema] |
| 34 | }) |
| 35 | await peer.ready() |
| 36 | await peer.mountOrg('alpha', ownerRoom.keyHex) |
| 37 | await replicateAndSync([owner.getOrgBase('alpha'), peer.getOrgBase('alpha')]) |
| 38 | |
| 39 | // Org record replicated (sanity). |
| 40 | const org = await peer.get('alpha') |
| 41 | t.is(org && org.displayName, 'Alpha', 'org record replicated to peer') |
| 42 | |
| 43 | // The org issue replicated WITH the org — no separate tracker. |
| 44 | const peerIssues = new HyperIssues(null, { room: peer.getOrgRoom('alpha'), ownsRoom: false }) |
| 45 | await peerIssues.ready() |
| 46 | const got = await peerIssues.get(id) |
| 47 | t.is(got && got.title, 'org issue', 'org issue replicated to peer via the org autobase') |
| 48 | |
| 49 | await ownerIssues.close() |
| 50 | await peerIssues.close() |
| 51 | await owner.close() |
| 52 | await peer.close() |
| 53 | }) |
| 54 | |
| 55 | // Control: WITHOUT extraSchemas the org room ignores issue ops, so the |
| 56 | // issue never materialises (proves the replication above is due to the |
| 57 | // composed schema, not some other path). |
| 58 | test('control: org room without issuesSchema does not store issues', async (t) => { |
| 59 | const owner = new HyperOrgs(new Corestore(tmp()), { namespace: 'owner' }) // no extraSchemas |
| 60 | await owner.ready() |
| 61 | await owner.create('beta', 'group', { displayName: 'Beta' }) |
| 62 | const room = owner.getOrgRoom('beta') |
| 63 | const issues = new HyperIssues(null, { room, ownsRoom: false }) |
| 64 | await issues.ready() |
| 65 | const id = await issues.create({ title: 'ignored', author: 'owner' }) |
| 66 | const got = await issues.get(id) |
| 67 | t.absent(got, 'issue op ignored when org room has no issuesSchema composed') |
| 68 | await issues.close() |
| 69 | await owner.close() |
| 70 | }) |