Some checks failed
build / lint (22) (push) Failing after 17s
build / test (22) (push) Failing after 8s
build / lint (23) (push) Failing after 2s
build / build (22) (push) Has been skipped
build / build (23) (push) Has been skipped
build / test (23) (push) Failing after 4s
docsearch / docsearch (push) Failing after 1s
188 lines
4.8 KiB
TypeScript
188 lines
4.8 KiB
TypeScript
import test from 'ava'
|
|
import * as Y from 'yjs'
|
|
import { retryableAssertion } from '../utils/retryableAssertion.ts'
|
|
import { newHocuspocus, newHocuspocusProvider, sleep } from '../utils/index.ts'
|
|
|
|
test("initially doesn't have unsynced changes", async t => {
|
|
return new Promise(async resolve => {
|
|
|
|
const server = await newHocuspocus(t)
|
|
|
|
const provider = newHocuspocusProvider(t, server)
|
|
|
|
t.is(provider.hasUnsyncedChanges, false)
|
|
t.is(provider.synced, false)
|
|
|
|
setTimeout(() => {
|
|
t.is(provider.hasUnsyncedChanges, false)
|
|
t.is(provider.synced, true)
|
|
|
|
resolve()
|
|
}, 200)
|
|
})
|
|
})
|
|
|
|
test('has unsynced changes when updating', async t => {
|
|
const server = await newHocuspocus(t)
|
|
|
|
const provider = newHocuspocusProvider(t, server, {
|
|
awareness: undefined,
|
|
})
|
|
|
|
provider.document.getMap('test').set('foo', 'bar')
|
|
t.is(provider.hasUnsyncedChanges, true)
|
|
|
|
// changes are synced
|
|
await retryableAssertion(t, tt => {
|
|
tt.is(provider.hasUnsyncedChanges, false)
|
|
})
|
|
})
|
|
|
|
test('has unsynced changes when in readonly mode', async t => {
|
|
const server = await newHocuspocus(t, {
|
|
async onAuthenticate({ connectionConfig }) {
|
|
connectionConfig.readOnly = true
|
|
},
|
|
})
|
|
|
|
const provider = newHocuspocusProvider(t, server, { token: 'readonly' })
|
|
|
|
provider.document.getMap('test').set('foo', 'bar')
|
|
|
|
await retryableAssertion(t, tt => {
|
|
tt.is(provider.hasUnsyncedChanges, true)
|
|
})
|
|
|
|
await sleep(100)
|
|
|
|
// confirm that the changes are not synced later either
|
|
t.is(provider.hasUnsyncedChanges, true)
|
|
})
|
|
|
|
test('has no unsynced changes when in readonly mode and no changes', async t => {
|
|
const server = await newHocuspocus(t, {
|
|
async onAuthenticate({ connectionConfig }) {
|
|
connectionConfig.readOnly = true
|
|
},
|
|
})
|
|
|
|
const provider = newHocuspocusProvider(t, server, { token: 'readonly' })
|
|
|
|
// first, unsyncedChanges is briefly set to true when we're waiting for the ack of the initial sync
|
|
await new Promise((resolve, reject) => {
|
|
provider.on('unsyncedChanges', () => {
|
|
provider.off('unsyncedChanges')
|
|
if (provider.hasUnsyncedChanges) {
|
|
resolve('done')
|
|
} else {
|
|
reject()
|
|
}
|
|
})
|
|
})
|
|
|
|
// then, it should be set to false when the sync message is confirmed
|
|
await retryableAssertion(t, tt => {
|
|
tt.is(provider.hasUnsyncedChanges, false)
|
|
})
|
|
})
|
|
|
|
test('has unsynced changes when in readonly mode and receiving external update', async t => {
|
|
const server = await newHocuspocus(t, {
|
|
async onAuthenticate({ connectionConfig, token }) {
|
|
if (token === 'readonly') {
|
|
connectionConfig.readOnly = true
|
|
}
|
|
},
|
|
})
|
|
|
|
const provider = newHocuspocusProvider(t, server, {
|
|
token: 'readonly',
|
|
})
|
|
|
|
provider.document.getMap('test').set('foo', 'bar')
|
|
|
|
t.is(provider.hasUnsyncedChanges, true)
|
|
|
|
await sleep(100)
|
|
|
|
t.is(provider.hasUnsyncedChanges, true)
|
|
|
|
const provider2 = newHocuspocusProvider(t, server, {
|
|
token: 'full-access',
|
|
})
|
|
|
|
provider2.document.getMap('test2').set('foo', 'bar')
|
|
|
|
t.is(provider2.hasUnsyncedChanges, true)
|
|
|
|
await retryableAssertion(t, tt => {
|
|
tt.is(provider2.hasUnsyncedChanges, false)
|
|
})
|
|
|
|
t.is(provider.hasUnsyncedChanges, true)
|
|
})
|
|
|
|
test('has unsynced changes when in readonly mode and initial document has changed', async t => {
|
|
const server = await newHocuspocus(t, {
|
|
async onAuthenticate({ connectionConfig }) {
|
|
connectionConfig.readOnly = true
|
|
},
|
|
})
|
|
|
|
const document = new Y.Doc()
|
|
document.getMap('test').set('foo', 'bar')
|
|
|
|
const provider = newHocuspocusProvider(t, server, { document, token: 'readonly' })
|
|
|
|
await retryableAssertion(t, tt => {
|
|
tt.is(provider.hasUnsyncedChanges, true)
|
|
})
|
|
|
|
await sleep(100)
|
|
|
|
t.is(provider.hasUnsyncedChanges, true)
|
|
})
|
|
|
|
test('has unsynced changes when in readonly mode and initial document has changed (deletion)', async t => {
|
|
const document = new Y.Doc()
|
|
document.getMap('test').set('foo', 'bar')
|
|
const initialState = Y.encodeStateAsUpdate(document)
|
|
|
|
const server = await newHocuspocus(t, {
|
|
async onLoadDocument() {
|
|
return initialState
|
|
},
|
|
async onAuthenticate({ connectionConfig }) {
|
|
connectionConfig.readOnly = true
|
|
},
|
|
})
|
|
|
|
document.getMap('test').delete('foo')
|
|
|
|
const provider = newHocuspocusProvider(t, server, { document, token: 'readonly' })
|
|
|
|
await retryableAssertion(t, tt => {
|
|
tt.is(provider.hasUnsyncedChanges, true)
|
|
})
|
|
|
|
await sleep(100)
|
|
|
|
t.is(provider.hasUnsyncedChanges, true)
|
|
})
|
|
|
|
test('has no unsynced changes when in readonly mode and initial document has not changed', async t => {
|
|
const server = await newHocuspocus(t, {
|
|
async onAuthenticate({ connectionConfig }) {
|
|
connectionConfig.readOnly = true
|
|
},
|
|
})
|
|
|
|
const document = new Y.Doc()
|
|
|
|
const provider = newHocuspocusProvider(t, server, { document, token: 'readonly' })
|
|
|
|
await sleep(200)
|
|
|
|
t.is(provider.hasUnsyncedChanges, false)
|
|
})
|