Skip to content

Commit

Permalink
Merge 662cf80 into 71b2839
Browse files Browse the repository at this point in the history
  • Loading branch information
Tornquist committed Dec 6, 2018
2 parents 71b2839 + 662cf80 commit eaecbf7
Show file tree
Hide file tree
Showing 4 changed files with 342 additions and 78 deletions.
12 changes: 6 additions & 6 deletions modules/Category.js
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ module.exports = class Category {
this.props.name = newName
}

get account_id() { return this.props.account_id }
get accountID() { return this.props.account_id }
set account(newAccount) {
this._modifiedProps.push("account_id")
let id = (typeof newAccount === "number") ? newAccount : newAccount.id
Expand All @@ -169,11 +169,11 @@ module.exports = class Category {
let isValidNewParent = isCategory
if (!isValidNewParent) throw TimeError.Request.INVALID_TYPE

this.parent_id = newParent
this.parentID = newParent
}

get parent_id() { return this.props.parent_id }
set parent_id(newParent) {
get parentID() { return this.props.parent_id }
set parentID(newParent) {
let id = (typeof newParent === "number") ? newParent : newParent.id
this.props.parent_id = id
this._modifiedProps.push('parent_id')
Expand All @@ -189,9 +189,9 @@ module.exports = class Category {

this.id = data.id
this.props = {
parent_id: data.parent_id,
parent_id: data.parent_id || data.parentID,
name: data.name,
account_id: data.account_id
account_id: data.account_id || data.accountID
}
}

Expand Down
79 changes: 71 additions & 8 deletions modules/Entry.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
'use strict'

const TimeError = require("./TimeError")
const Type = require("./Type")
const TimeError = require('./TimeError')
const Type = require('./Type')

const dateHelper = require('../helpers/date')
const arrayHelper = require('../helpers/array')
Expand Down Expand Up @@ -71,6 +71,32 @@ async function fetchRecords(filters, limit = null) {
delete filters.type
}

let accountFilter = null;
if (filters.account_id !== undefined || filters.account_ids !== undefined) {
accountFilter = [filters.account_id].concat(filters.account_ids || []).filter(x => !!x)
delete filters.account_id
delete filters.account_ids
}

let categoryFilter = null;
if (filters.category_id !== undefined || filters.category_ids !== undefined) {
categoryFilter = [filters.category_id].concat(filters.category_ids || []).filter(x => !!x)
delete filters.category_id
delete filters.category_ids
}

let greaterThanFilter = null;
if (filters.date_gt !== undefined) {
greaterThanFilter = dateHelper.toDb(filters.date_gt)
delete filters.date_gt
}

let lessThanFilter = null;
if (filters.date_lt !== undefined) {
lessThanFilter = dateHelper.toDb(filters.date_lt)
delete filters.date_lt
}

let data;
try {
let query = db.select(
Expand All @@ -81,12 +107,26 @@ async function fetchRecords(filters, limit = null) {
'ended_at'
).from('entry')
.leftJoin('entry_type', 'entry_type.id', 'entry.type_id')
.where(filters)

if (limit !== null) {
query = query.limit(+limit)
if (accountFilter !== null) {
query = query.leftJoin('category', 'category.id', 'entry.category_id')
.leftJoin('account', 'account.id', 'category.account_id')
}

if (Object.keys(filters).length > 0)
query = query.where(filters)
if (accountFilter !== null)
query = query.whereIn('account.id', accountFilter)
if (categoryFilter !== null)
query = query.whereIn('entry.category_id', categoryFilter)
if (greaterThanFilter !== null)
query = query.where('started_at', '>', greaterThanFilter)
if (lessThanFilter !== null)
query = query.where('started_at', '<', lessThanFilter)

if (limit !== null)
query = query.limit(+limit)

data = await query
} catch (error) {
return Promise.reject(TimeError.Data.BAD_CONNECTION)
Expand All @@ -96,6 +136,9 @@ async function fetchRecords(filters, limit = null) {
}

module.exports = class Entry {
get categoryID() {
return this.props.category_id
}
set category(newCategory) {
this._modifiedProps.push("category_id")
let category_id = typeof newCategory === "object" ? newCategory.id : newCategory
Expand Down Expand Up @@ -149,7 +192,7 @@ module.exports = class Entry {
this.props = {
type: data.type,

category_id: data.category_id,
category_id: data.category_id || data.categoryID,

started_at: data.started_at,
ended_at: data.ended_at
Expand All @@ -175,6 +218,11 @@ module.exports = class Entry {
updateRecord.bind(this)()
}

async delete() {
let db = require('../lib/db')()
await db('entry').where('id', this.id).del()
}

static async fetch(id) {
let objectData = await fetchRecords({ id }, 1)
if (objectData.length == 0) {
Expand All @@ -184,11 +232,26 @@ module.exports = class Entry {
}

static async findFor(search) {
if (search.category) {
search.category_id = search.category.id
if (search.category || search.categories) {
let categories = [search.category].concat(search.categories || []).filter(x => !!x)
search.category_ids = categories.map(c => c.id)
delete search.category
delete search.categories
}
if (search.account || search.accounts) {
let accounts = [search.account].concat(search.accounts || []).filter(x => !!x)
search.account_ids = accounts.map(c => c.id)
delete search.account
delete search.accounts
}

Object.keys(search).forEach(key => {
if (key.endsWith('ID') || key.endsWith('IDs')) {
search[key.replace('ID', '_id')] = search[key]
delete search[key]
}
})

let records = await fetchRecords(search)
return records.map(record => new Entry(record))
}
Expand Down
70 changes: 35 additions & 35 deletions test/test-category.js
Original file line number Diff line number Diff line change
Expand Up @@ -67,10 +67,10 @@ describe('Category Module', () => {
let accountRootNode = await Time._db.select('id')
.from('category')
.whereNull('parent_id')
.andWhere('account_id', category.account_id)
.andWhere('account_id', category.accountID)
.then(results => (results[0] || {}).id)

category.parent_id.should.eq(accountRootNode)
category.parentID.should.eq(accountRootNode)
})

it('can be created with parent and no account', async () => {
Expand All @@ -80,7 +80,7 @@ describe('Category Module', () => {

await newCategory.save()

newCategory.account_id.should.eq(category.account_id)
newCategory.accountID.should.eq(category.accountID)
})

it('will be rejected if category and parent are mismatched', () => {
Expand All @@ -106,7 +106,7 @@ describe('Category Module', () => {
let newCategory = new Time.Category()
newCategory.name = 'Will throw'

newCategory.parent_id = 10000
newCategory.parentID = 10000

return newCategory.save()
.should.be.rejectedWith(Time.Error.Data.NOT_FOUND)
Expand All @@ -130,7 +130,7 @@ describe('Category Module', () => {

it('will load with the expected values', done => {
category.name.should.eq(startingName)
category.account_id.should.eq(accountTree.account.id)
category.accountID.should.eq(accountTree.account.id)
done()
})

Expand Down Expand Up @@ -162,7 +162,7 @@ describe('Category Module', () => {
})

it('allows allows all categories to be loaded with an id', async () => {
let categories = await Time.Category.findForAccount(category.account_id)
let categories = await Time.Category.findForAccount(category.accountID)

categories.length.should.eq(3)
})
Expand Down Expand Up @@ -215,7 +215,7 @@ describe('Category Module', () => {

it("allows saving and will return the parent object", async () => {
await child.save()
child.parent_id.should.eq(parent.id)
child.parentID.should.eq(parent.id)
})

it("allows retrieval of the parent object", async () => {
Expand Down Expand Up @@ -248,22 +248,22 @@ describe('Category Module', () => {
before(async () => {
categoryA = new Time.Category({
name: "A",
account_id: accountTree.account.id
accountID: accountTree.account.id
})
await categoryA.save()
categoryB = new Time.Category({
name: "B",
account_id: accountTree.account.id
accountID: accountTree.account.id
})
await categoryB.save()
categoryC = new Time.Category({
name: "C",
account_id: secondAccountTree.account.id
accountID: secondAccountTree.account.id
})
await categoryC.save()
categoryD = new Time.Category({
name: "D",
account_id: secondAccountTree.account.id
accountID: secondAccountTree.account.id
})
await categoryD.save()
})
Expand All @@ -273,15 +273,15 @@ describe('Category Module', () => {
await categoryA.save()

let fresh = await Time.Category.fetch(categoryA.id)
categoryA.parent_id.should.eq(categoryB.id)
categoryA.parentID.should.eq(categoryB.id)
})

it('Allows moving between accounts with account alone', async () => {
categoryC.account = categoryA.account_id
categoryC.account = categoryA.accountID
await categoryC.save()

let fresh = await Time.Category.fetch(categoryC.id)
categoryC.account_id.should.eq(categoryA.account_id)
categoryC.accountID.should.eq(categoryA.accountID)
})

it('Allows moving between accounts with parent alone', async () => {
Expand All @@ -293,19 +293,19 @@ describe('Category Module', () => {

// B points to second account root (same as D)
// Original object will be updated as well
categoryB.parent_id.should.eq(categoryD.id)
categoryB.account_id.should.eq(categoryD.account_id)
categoryB.parentID.should.eq(categoryD.id)
categoryB.accountID.should.eq(categoryD.accountID)

freshB.parent_id.should.eq(categoryD.id)
freshB.account_id.should.eq(categoryD.account_id)
freshB.parentID.should.eq(categoryD.id)
freshB.accountID.should.eq(categoryD.accountID)

// Children come with. Fresh objects have correct values
freshA.parent_id.should.eq(categoryB.id)
freshA.account_id.should.eq(categoryD.account_id)
freshA.parentID.should.eq(categoryB.id)
freshA.accountID.should.eq(categoryD.accountID)

// Old objects will be out of date
categoryA.parent_id.should.eq(categoryB.id)
categoryA.account_id.should.not.eq(categoryD.account_id)
categoryA.parentID.should.eq(categoryB.id)
categoryA.accountID.should.not.eq(categoryD.accountID)

// Update records for other tests
categoryA = freshA
Expand All @@ -314,16 +314,16 @@ describe('Category Module', () => {

it('Allows moving between accounts with parent and account when they match', async () => {
categoryC.parent = categoryD
categoryC.account = categoryB.account_id
categoryC.account = categoryB.accountID
await categoryC.save()

let fresh = await Time.Category.fetch(categoryC.id)

categoryC.parent_id.should.eq(categoryD.id)
fresh.parent_id.should.eq(categoryD.id)
categoryC.parentID.should.eq(categoryD.id)
fresh.parentID.should.eq(categoryD.id)

categoryC.account_id.should.eq(categoryD.account_id)
fresh.account_id.should.eq(categoryD.account_id)
categoryC.accountID.should.eq(categoryD.accountID)
fresh.accountID.should.eq(categoryD.accountID)
})

it('Denies moving between accounts with parent and account when they are inconsistent', () => {
Expand All @@ -350,31 +350,31 @@ describe('Category Module', () => {

categoryA = new Time.Category({
name: "A",
account_id: accountTree.account.id
accountID: accountTree.account.id
})
await categoryA.save()

categoryB = new Time.Category({
name: "B",
account_id: accountTree.account.id
accountID: accountTree.account.id
})
await categoryB.save()

categoryC = new Time.Category({
name: "C",
parent_id: categoryB.id
parentID: categoryB.id
})
await categoryC.save()

categoryD = new Time.Category({
name: "D",
parent_id: categoryB.id
parentID: categoryB.id
})
await categoryD.save()

categoryE = new Time.Category({
name: "E",
parent_id: categoryA.id
parentID: categoryA.id
})
await categoryE.save()
})
Expand All @@ -389,7 +389,7 @@ describe('Category Module', () => {
})

it('allows children to be moved up to the parent\'s level', async () => {
let parentID = categoryB.parent_id
let parentID = categoryB.parentID

await categoryB.delete(false)

Expand All @@ -399,8 +399,8 @@ describe('Category Module', () => {
let freshC = await Time.Category.fetch(categoryC.id)
let freshD = await Time.Category.fetch(categoryD.id)

freshC.parent_id.should.eq(parentID)
freshD.parent_id.should.eq(parentID)
freshC.parentID.should.eq(parentID)
freshD.parentID.should.eq(parentID)
})

it('allows leaf nodes to be deleted', async () => {
Expand Down

0 comments on commit eaecbf7

Please sign in to comment.