diff --git a/gathering/app/controllers/sync.js b/gathering/app/controllers/sync.js index 865fbfe0..4c366d9b 100644 --- a/gathering/app/controllers/sync.js +++ b/gathering/app/controllers/sync.js @@ -11,6 +11,7 @@ import { task } from 'ember-concurrency'; import { storageFor } from 'ember-local-storage'; import stringify from 'json-stringify-safe'; +import { TrackedArray } from 'tracked-built-ins'; export default class SyncController extends Controller { @storageFor('databases') @@ -20,6 +21,8 @@ export default class SyncController extends Controller { @tracked result; @tracked error; + @tracked conflicts; + @tracked syncPromise; @tracked isSyncing = false; @@ -39,23 +42,55 @@ export default class SyncController extends Controller { config.emberPouch.options, ); - const syncPromise = sourceDb.sync(destinationDb); + /* + const changes = sourceDb + .changes({ live: true, include_docs: true, conflicts: true }) + .on('change', (info) => { + if (info.doc._conflicts) { + console.log('confl???', info); + this.conflicts.push(info.doc); + } + }) + .on('error', (error) => { + console.log('error with changes:', stringify(error)); + this.error = error; + }); + */ + + const syncPromise = sourceDb.sync(destinationDb, { conflicts: true }); + // .on('error', (error) => { + // console.log('error with sync:', stringify(error)); + // this.error = error; + // }) + // .on('change', (info) => { + // console.log('change with sync:', stringify(info)); + // this.result = info; + // }); this.result = undefined; this.syncPromise = syncPromise; + this.conflicts = new TrackedArray(); - yield syncPromise - .then((result) => { - run(() => { - this.result = result; - }); - }) - .catch((error) => { - run(() => { - console.log('error with sync:', stringify(error)); - this.error = error; - }); + try { + let result = yield syncPromise; + this.result = result; + + let allDocs = yield sourceDb.allDocs({ + include_docs: true, + conflicts: true, + }); + + allDocs.rows.forEach((row) => { + if (row.doc._conflicts) { + this.conflicts.push(row.doc); + } }); + } catch (error) { + console.log('error with sync:', stringify(error)); + this.error = error; + } + + // changes.cancel(); }) sync; diff --git a/gathering/app/templates/sync.hbs b/gathering/app/templates/sync.hbs index 65a64f84..22774b60 100644 --- a/gathering/app/templates/sync.hbs +++ b/gathering/app/templates/sync.hbs @@ -111,6 +111,17 @@ {{/if}} + {{#if this.conflicts.length}} +

Conflicts

+ + {{/if}} + Version: {{this.version}} diff --git a/gathering/tests/acceptance/sync-test.js b/gathering/tests/acceptance/sync-test.js index 454636a0..5a8fd6a0 100644 --- a/gathering/tests/acceptance/sync-test.js +++ b/gathering/tests/acceptance/sync-test.js @@ -1,28 +1,25 @@ import { run } from '@ember/runloop'; -import { visit } from '@ember/test-helpers'; +import { visit, waitUntil } from '@ember/test-helpers'; +import PouchDB from 'adventure-gathering/utils/pouch'; import { setupApplicationTest } from 'ember-qunit'; import { module, test } from 'qunit'; +import regionsPage from '../pages/regions'; import page from '../pages/sync'; module('Acceptance | sync', function (hooks) { setupApplicationTest(hooks); - hooks.beforeEach(function (assert) { + hooks.beforeEach(async function () { const store = this.owner.lookup('service:store'); - const done = assert.async(); - run(() => { - const fixture = store.createRecord('destination'); + const fixture = store.createRecord('destination'); - fixture.set('description', 'Ina-Karekh'); + fixture.set('description', 'Ina-Karekh'); - fixture.save().then(() => { - done(); - }); - }); + await fixture.save(); }); // I had these as separate tests but localStorage was bleeding through… ugh @@ -68,4 +65,45 @@ module('Acceptance | sync', function (hooks) { assert.strictEqual(page.databases.length, 2); }); + + test('shows when there are conflicts', async function (assert) { + let store = this.owner.lookup('service:store'); + + let region = store.createRecord('region', { + name: 'A region', + }); + + await region.save(); + + await visit('/'); + await page.visit(); + await page.destination.fillIn('eventual-conflicts'); + await page.sync(); + + let otherDb = new PouchDB('eventual-conflicts', { + adapter: 'memory', + }); + + let regionDoc = (await otherDb.allDocs()).rows.find((row) => + row.id.includes('region'), + ); + + await otherDb.put({ + _id: regionDoc.id, + _rev: regionDoc.value.rev, + name: 'A region version 100', + }); + + await regionsPage.visit(); + + await regionsPage.regions[0].edit(); + await regionsPage.nameField.fill('A region version -100'); + await regionsPage.save(); + await waitUntil(() => regionsPage.regions.length); + + await page.visit(); + await page.sync(); + + assert.strictEqual(page.conflicts.length, 1); + }); }); diff --git a/gathering/tests/pages/sync.js b/gathering/tests/pages/sync.js index 27f802e8..4b0e9559 100644 --- a/gathering/tests/pages/sync.js +++ b/gathering/tests/pages/sync.js @@ -28,4 +28,6 @@ export default PageObject.create({ written: text('[data-test-written]'), writeFailures: text('[data-test-write-failures]'), }, + + conflicts: collection('[data-test-conflict]'), });