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
+
+ {{#each this.conflicts as |conflict|}}
+ -
+ {{conflict._id}}: {{#each conflict._conflicts as |rev|}}{{rev}} {{/each}}
+
+ {{/each}}
+
+ {{/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]'),
});