Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 47 additions & 12 deletions gathering/app/controllers/sync.js
Original file line number Diff line number Diff line change
Expand Up @@ -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')
Expand All @@ -20,6 +21,8 @@ export default class SyncController extends Controller {
@tracked result;
@tracked error;

@tracked conflicts;

@tracked syncPromise;
@tracked isSyncing = false;

Expand All @@ -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;

Expand Down
11 changes: 11 additions & 0 deletions gathering/app/templates/sync.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,17 @@
</code>
{{/if}}

{{#if this.conflicts.length}}
<h2 class='mt-4 text-2xl font-bold'>Conflicts</h2>
<ul class='border-2 border-red-500'>
{{#each this.conflicts as |conflict|}}
<li data-test-conflict>
{{conflict._id}}: {{#each conflict._conflicts as |rev|}}{{rev}} {{/each}}
</li>
{{/each}}
</ul>
{{/if}}

Version:
{{this.version}}
</div>
Expand Down
58 changes: 48 additions & 10 deletions gathering/tests/acceptance/sync-test.js
Original file line number Diff line number Diff line change
@@ -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
Expand Down Expand Up @@ -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);
});
});
2 changes: 2 additions & 0 deletions gathering/tests/pages/sync.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,4 +28,6 @@ export default PageObject.create({
written: text('[data-test-written]'),
writeFailures: text('[data-test-write-failures]'),
},

conflicts: collection('[data-test-conflict]'),
});