Skip to content

Commit

Permalink
Merge pull request #1179 from cozy-labs/test-builders
Browse files Browse the repository at this point in the history
test/builders: Improvements
  • Loading branch information
sebn committed Sep 24, 2018
2 parents e20281f + 24a160f commit cfd4ed0
Show file tree
Hide file tree
Showing 17 changed files with 187 additions and 212 deletions.
10 changes: 10 additions & 0 deletions core/metadata.js
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ module.exports = {
ensureValidChecksum,
extractRevNumber,
isUpToDate,
markAsUpToDate,
sameFolder,
sameFile,
sameFileIgnoreRev,
Expand Down Expand Up @@ -247,6 +248,15 @@ function isUpToDate (side /*: SideName */, doc /*: Metadata */) {
return currentRev === lastRev
}

function markAsUpToDate (doc /*: Metadata */) {
let rev = extractRevNumber(doc) + 1
for (let s of ['local', 'remote']) {
doc.sides[s] = rev
}
delete doc.errors
return rev
}

// Ensure new timestamp is never older than the previous one
function assignMaxDate (doc /*: Metadata */, was /*: ?Metadata */) {
if (was == null) return
Expand Down
13 changes: 7 additions & 6 deletions core/sync.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,12 @@ const _ = require('lodash')

const { MAX_SYNC_ATTEMPTS } = require('./constants')
const logger = require('./logger')
const { extractRevNumber, isUpToDate, markSide, sameFileIgnoreRev } = require('./metadata')
const {
isUpToDate,
markAsUpToDate,
markSide,
sameFileIgnoreRev
} = require('./metadata')
const userActionRequired = require('./remote/user_action_required')
const { HEARTBEAT } = require('./remote/watcher')
const { otherSide } = require('./side')
Expand Down Expand Up @@ -433,11 +438,7 @@ class Sync {

// Update rev numbers for both local and remote sides
async updateRevs (doc /*: Metadata */, side /*: SideName */) /*: Promise<*> */ {
let rev = extractRevNumber(doc) + 1
for (let s of ['local', 'remote']) {
doc.sides[s] = rev
}
delete doc.errors
const rev = markAsUpToDate(doc)
try {
await this.pouch.put(doc)
} catch (err) {
Expand Down
4 changes: 2 additions & 2 deletions test/integration/move.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ const path = require('path')
const should = require('should')

const Builders = require('../support/builders')
const pouchdbBuilders = require('../support/builders/pouchdb')
const dbBuilders = require('../support/builders/db')
const configHelpers = require('../support/helpers/config')
const cozyHelpers = require('../support/helpers/cozy')
const pouchHelpers = require('../support/helpers/pouch')
Expand Down Expand Up @@ -94,7 +94,7 @@ suite('Move', () => {
updated_at: '2017-06-19T08:19:26.769Z',
remote: {
_id: file._id,
_rev: pouchdbBuilders.rev()
_rev: dbBuilders.rev()
}
}
), oldFile)
Expand Down
6 changes: 3 additions & 3 deletions test/integration/platform_incompatibilities.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,8 @@ suite('Platform incompatibilities', () => {
})

test('add incompatible dir and file', async () => {
await builders.remote.dir().named('di:r').create()
await builders.remote.file().named('fi:le').create()
await builders.remote.dir().name('di:r').create()
await builders.remote.file().name('fi:le').create()
await helpers.pullAndSyncAll()
should(await helpers.local.tree()).be.empty()
should(await helpers.incompatibleTree()).deepEqual([
Expand All @@ -55,7 +55,7 @@ suite('Platform incompatibilities', () => {
])
})
test('add incompatible dir with two colons', async () => {
await builders.remote.dir().named('d:i:r').create()
await builders.remote.dir().name('d:i:r').create()
await helpers.pullAndSyncAll()
should(await helpers.local.tree()).be.empty()
should(await helpers.incompatibleTree()).deepEqual([
Expand Down
4 changes: 2 additions & 2 deletions test/integration/update.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ describe('Update file', () => {
// OPTIMIZE: Don't trigger useless remote sync for local inode-only change
it('works but triggers useless remote sync', async () => {
const file = await builders.remote.file()
.named('file')
.name('file')
.data('Initial content')
.create()
await helpers.remote.pullChanges()
Expand All @@ -61,7 +61,7 @@ describe('Update file', () => {
describe('older timestamp change', () => {
it('should keep the most recent timestamp to prevent 422 errors', async () => {
const file = await builders.remote.file()
.named('file')
.name('file')
.data('Initial content')
.timestamp(2018, 5, 15, 21, 1, 53)
.create()
Expand Down
15 changes: 15 additions & 0 deletions test/support/builders/db.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
/* @flow */

/** Test data builders common to both CouchDB and PouchDB */

const uuid = require('uuid/v4')

module.exports = {
id () /*: string */ {
return uuid().replace(/-/g, '')
},

rev (shortRev /*: number */ = 1) /*: string */ {
return `${shortRev}-${this.id()}`
}
}
69 changes: 27 additions & 42 deletions test/support/builders/metadata/base.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,12 @@ const _ = require('lodash')

const {
assignId,
assignPlatformIncompatibilities
assignPlatformIncompatibilities,
id
} = require('../../../../core/metadata')
const timestamp = require('../../../../core/timestamp')

const pouchdbBuilders = require('../pouchdb')
const dbBuilders = require('../db')

/*::
import type fs from 'fs-extra'
Expand All @@ -24,32 +25,27 @@ import type Pouch from '../../../../core/pouch'
module.exports = class BaseMetadataBuilder {
/*::
pouch: ?Pouch
opts: {
_rev?: string,
path: string,
ino?: number,
remote: MetadataRemoteInfo,
updated_at?: string|Date,
trashed?: true,
sides: MetadataSidesInfo
}
doc: Metadata
*/

constructor (pouch /*: ?Pouch */) {
this.pouch = pouch
this.opts = {
this.doc = {
_id: id('foo'),
docType: 'folder', // To make flow happy (overridden by subclasses)
path: 'foo',
remote: {
_id: pouchdbBuilders.id(),
_rev: pouchdbBuilders.rev()
_id: dbBuilders.id(),
_rev: dbBuilders.rev()
},
tags: [],
sides: {},
updated_at: timestamp.stringify(timestamp.current())
}
}

rev (rev /*: string */) /*: this */ {
this.opts._rev = rev
this.doc._rev = rev
return this
}

Expand All @@ -66,7 +62,7 @@ module.exports = class BaseMetadataBuilder {
}

ino (ino /*: number */) /*: this */ {
this.opts.ino = ino
this.doc.ino = ino
return this
}

Expand All @@ -75,79 +71,68 @@ module.exports = class BaseMetadataBuilder {
}

path (path /*: string */) /*: this */ {
this.opts.path = path
this.doc.path = path
assignId(this.doc)
return this
}

trashed () /*: this */ {
this.opts.trashed = true
this.doc.trashed = true
return this
}

updatedAt (date /*: Date */) /*: this */ {
this.opts.updated_at = timestamp.fromDate(date).toISOString()
this.doc.updated_at = timestamp.fromDate(date).toISOString()
return this
}

newerThan (doc /*: Metadata */) /*: this */ {
this.opts.updated_at = new Date(timestamp.fromDate(doc.updated_at) + 2000)
this.doc.updated_at = new Date(timestamp.fromDate(doc.updated_at) + 2000)
return this
}

olderThan (doc /*: Metadata */) /*: this */ {
this.opts.updated_at = new Date(timestamp.fromDate(doc.updated_at) - 2000)
this.doc.updated_at = new Date(timestamp.fromDate(doc.updated_at) - 2000)
return this
}

remoteId (_id /*: string */) /*: this */ {
this.opts.remote = {
this.doc.remote = {
_id,
_rev: pouchdbBuilders.rev()
_rev: dbBuilders.rev()
}
return this
}

upToDate () /*: this */ {
this.opts.sides = {local: 2, remote: 2}
this.doc.sides = {local: 2, remote: 2}
return this
}

notUpToDate () /*: this */ {
this.opts.sides = {remote: 1}
this.doc.sides = {remote: 1}
return this
}

sides (sides /*: MetadataSidesInfo */) /*: this */ {
this.opts.sides = sides
this.doc.sides = sides
return this
}

attributesByType () /*: * */ {
throw new Error('BaseMetadataBuilder#attributesByType() not implemented')
}

build () /*: Metadata */ {
const doc = _.merge({
_id: '',
tags: [],
updated_at: new Date()
}, this.opts, this.attributesByType())

assignId(doc)
// Don't detect incompatibilities according to syncPath for test data, to
// prevent environment related failures.
assignPlatformIncompatibilities(doc, '')
assignPlatformIncompatibilities(this.doc, '')

return doc
return _.cloneDeep(this.doc)
}

async create () /*: Promise<Metadata> */ {
const doc = this.build()
if (this.pouch == null) {
throw new Error('Cannot create dir metadata without Pouch')
}
const doc = this.build()
// $FlowFixMe
const {rev} = await this.pouch.put(doc)
const { rev } = await this.pouch.put(doc)
doc._rev = rev
return doc
}
Expand Down
11 changes: 7 additions & 4 deletions test/support/builders/metadata/dir.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,13 @@

const BaseMetadataBuilder = require('./base')

/*::
import type Pouch from '../../../../core/pouch'
*/

module.exports = class DirMetadataBuilder extends BaseMetadataBuilder {
attributesByType () /*: * */ {
return {
docType: 'folder'
}
constructor (pouch /*: ?Pouch */) {
super(pouch)
this.doc.docType = 'folder'
}
}
35 changes: 11 additions & 24 deletions test/support/builders/metadata/file.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
/* @flow */

const _ = require('lodash')
const crypto = require('crypto')

const { createMetadata } = require('../../../../core/conversion')
const { ensureValidPath } = require('../../../../core/metadata')
const {
assignId,
ensureValidPath
} = require('../../../../core/metadata')

const BaseMetadataBuilder = require('./base')

Expand All @@ -14,38 +16,23 @@ import type { RemoteDoc } from '../../../../core/remote/document'
*/

module.exports = class FileMetadataBuilder extends BaseMetadataBuilder {
/*::
fileOpts: {
docType: 'file',
size: number,
md5sum: string
}
*/

constructor (pouch /*: ?Pouch */) {
super(pouch)
this.fileOpts = {
docType: 'file',
size: 0,
md5sum: '1B2M2Y8AsgTpgAmY7PhCfg==' // empty
}
this.doc.docType = 'file'
this.data('')
}

fromRemote (remoteDoc /*: RemoteDoc */) /*: this */ {
const doc = createMetadata(remoteDoc)
ensureValidPath(doc)
this.opts = _.pick(doc, _.keys(this.opts))
this.doc = createMetadata(remoteDoc)
ensureValidPath(this.doc)
assignId(this.doc)
return this
}

data (data /*: string */) /*: this */ {
this.fileOpts.size = Buffer.from(data).length
this.fileOpts.md5sum =
this.doc.size = Buffer.from(data).length
this.doc.md5sum =
crypto.createHash('md5').update(data).digest().toString('base64')
return this
}

attributesByType () /*: * */ {
return this.fileOpts
}
}
11 changes: 0 additions & 11 deletions test/support/builders/pouchdb.js

This file was deleted.

Loading

0 comments on commit cfd4ed0

Please sign in to comment.