Skip to content

Commit

Permalink
Refactor extendLifetime out of the repository
Browse files Browse the repository at this point in the history
  • Loading branch information
pbu88 committed Sep 3, 2021
1 parent 35390f8 commit f6d28d4
Show file tree
Hide file tree
Showing 13 changed files with 1,602 additions and 104 deletions.
1,547 changes: 1,508 additions & 39 deletions backend/package-lock.json

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions backend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
"author": "",
"license": "ISC",
"dependencies": {
"@google-cloud/datastore": "6.5.0",
"asap": "^2.0.6",
"body-parser": "^1.13.3",
"connect-flash": "^0.1.1",
Expand Down
35 changes: 18 additions & 17 deletions backend/src/v2/ExtendLifetimeSharedDiffAction.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import {Metrics} from './Metrics';
import {SharedDiff, makePermanent} from './SharedDiff';
import {SharedDiff, makePermanent, extendLifetime} from './SharedDiff';
import {SharedDiffRepository} from './SharedDiffRepository';

export class ExtendLifetimeSharedDiffAction {
Expand All @@ -9,22 +9,23 @@ export class ExtendLifetimeSharedDiffAction {

extendSharedDiffLifetime(diff_id: string, numberOfHours: number): Promise<SharedDiff> {
return this.repository.fetchById(diff_id)
.then(diff => {
let newDate: Date = new Date(diff.expiresAt.getTime() + (numberOfHours * 60 * 60 * 1000));
if (newDate.getTime() - diff.created.getTime() >
ExtendLifetimeSharedDiffAction.MAX_LIFETIME_OF_DIFF_MS) {
return Promise.reject({
success: false,
message: 'Can\'t extend beyond the maximum lifetime of a diff which is 5 days.' +
' If this is needed, please fill a new issue on Github with the use case.'
});
}
})
.then(() => this.repository.extendLifetime(diff_id, numberOfHours))
.then(result => {
this.metrics.diffLifetimeExtendedSuccessfully();
return result;
});
.then(diff => {
let newDate: Date = new Date(diff.expiresAt.getTime() + (numberOfHours * 60 * 60 * 1000));
if (newDate.getTime() - diff.created.getTime() >
ExtendLifetimeSharedDiffAction.MAX_LIFETIME_OF_DIFF_MS) {
return Promise.reject({
success: false,
message: 'Can\'t extend beyond the maximum lifetime of a diff which is 5 days.' +
' If this is needed, please fill a new issue on Github with the use case.'
});
}
return extendLifetime(diff, numberOfHours);
})
.then(diff => this.repository.update(diff))
.then(result => {
this.metrics.diffLifetimeExtendedSuccessfully();
return result;
});
}

makePermanent(diff_id: string): Promise<SharedDiff> {
Expand Down
17 changes: 14 additions & 3 deletions backend/src/v2/SharedDiff.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import * as Diff2Html from 'diff2html';
import { DiffFile } from 'diff2html/lib/types';

const MAX_DIFF_DATE = new Date('9999-01-01');
const MAX_DIFF_DATE = new Date('9999-01-01');

export interface SharedDiff {
id?: string,
Expand All @@ -19,10 +19,21 @@ export function makeSharedDiff(raw_diff: string, createdDate: Date = new Date())
/**
* Returns a new SharedDiff with the expiresAt set at {@link MAX_DIFF_DATE}
* @param diff - a shared diff
* @returns a new SharedDiff
* @returns - a new SharedDiff
*/
export function makePermanent(diff: SharedDiff): SharedDiff {
return {...diff, expiresAt: MAX_DIFF_DATE }
return { ...diff, expiresAt: MAX_DIFF_DATE }
}

/**
* Returns a new SharedDiff with a expiresAt date set to further in the future (by number of hours).
* @param diff - a shared diff
* @param hours - the number of hours by which to extend the expire time date
* @returns - a new SharedDiff with the expiresAt date changed
*/
export function extendLifetime(diff: SharedDiff, hours: number): SharedDiff {
const newDate = new Date(diff.expiresAt.getTime() + (hours * 60 * 60 * 1000));
return { ...diff, expiresAt: newDate }
}

export function makeSharedDiffWithId(id: string, raw_diff: string, createdDate: Date, expireDate: Date): SharedDiff {
Expand Down
1 change: 0 additions & 1 deletion backend/src/v2/SharedDiffRepository.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,5 @@ export interface SharedDiffRepository {
insert: (diff: SharedDiff) => Promise<SharedDiff>;
fetchById: (id: string) => Promise<SharedDiff>;
deleteById: (id: string) => Promise<number>;
extendLifetime: (id: string, noOfDays: number) => Promise<SharedDiff>;
update(diff: SharedDiff): Promise<SharedDiff>;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
// Imports the Google Cloud client library
import { Datastore } from '@google-cloud/datastore';

import { makeSharedDiffWithId, SharedDiff } from '../SharedDiff';
import { SharedDiffRepository } from '../SharedDiffRepository';
const utils = require('../../utils.js').Utils;

const ENTITY_NAME = 'diffy'; // maybe should be SharedDiff
const MAX_DIFF_DATE = new Date('9999-01-01');

export class GoogleDatastoreDiffRepository implements SharedDiffRepository {
datastore: Datastore;

constructor(datastore: Datastore) {
this.datastore = datastore;
}

insert(diff: SharedDiff): Promise<SharedDiff> {
const url_id = utils.genRandomString()
const row = {
url_id: url_id,
rawDiff: diff.rawDiff,
created: diff.created,
expiresAt: diff.expiresAt
}
return this.datastore.save({
key: this.datastore.key("diffy"),
data: row
}).then(_ => ({ ...diff, id: url_id }));
}

update(diff: SharedDiff): Promise<SharedDiff> {
return null;
}

fetchById(id: string): Promise<SharedDiff> {
const query = this.datastore.createQuery("diffy")
.filter("url_id", "=", id)
.limit(1);
return this.datastore.runQuery(query)
.then(diffys => diffys[0][0])
.then(diffy => makeSharedDiffWithId(diffy.url_id, diffy.rawDiff, diffy.created, diffy.expiresAt));
}

// returns a promise of how many items where
// deleted
deleteById(id: string): Promise<number> {
return null;
}
}
12 changes: 0 additions & 12 deletions backend/src/v2/SharedDiffRepository/MongoSharedDiffRepository.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,18 +47,6 @@ export class MongoSharedDiffRepository implements SharedDiffRepository {
.then(doc => makeSharedDiffWithId(doc._id, doc.rawDiff, doc.created, doc.expiresAt));
}

extendLifetime(id: string, hours: number): Promise<SharedDiff> {
return this.fetchById(id)
.then(sharedDiff => new Date(sharedDiff.expiresAt.getTime() + (hours * 60 * 60 * 1000)))
.then(
newExpiredDate => {this.client.then(client => client.db(this.db_name))
.then(db => db.collection(COLLECTION_NAME))
.then(
collection => collection.updateOne(
{'_id': id}, {$set: {expiresAt: newExpiredDate}}))})
.then(updateResult => this.fetchById(id));
}

// returns a promise of how many items where
// deleted
deleteById(id: string): Promise<number> {
Expand Down
2 changes: 0 additions & 2 deletions backend/tests/v2/CreateSharedDiffAPIAction.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ index 1456e89..e1da2da 100644
insert: jest.fn(diff => Promise.resolve(diff)),
fetchById: (id: string) => null,
deleteById: (id: string) => Promise.resolve(0),
extendLifetime: jest.fn(diff => Promise.resolve(diff)),
update: (diff: SharedDiff) => Promise.reject('random err'),
};
const action = new CreateSharedDiffAPIAction(repo, metrics);
Expand Down Expand Up @@ -49,7 +48,6 @@ index 1456e89..e1da2da 100644
insert: jest.fn((diff) => Promise.reject(new Error('fake error'))),
fetchById: (id: string) => null,
deleteById: (id: string) => Promise.resolve(0),
extendLifetime: jest.fn(diff => Promise.reject('random err')),
update: (diff: SharedDiff) => Promise.resolve(diff),
};
const action = new CreateSharedDiffAPIAction(repo, metrics);
Expand Down
3 changes: 0 additions & 3 deletions backend/tests/v2/CreateSharedDiffAction.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ index 1456e89..e1da2da 100644
insert: jest.fn(diff => Promise.resolve(diff)),
fetchById: (id: string) => null,
deleteById: (id: string) => Promise.resolve(0),
extendLifetime: (id: string, noOfDays: number) => Promise.reject('random err'),
update: (diff: SharedDiff) => Promise.reject('random err'),
};
const action = new CreateSharedDiffAction(repo, metrics);
Expand Down Expand Up @@ -49,7 +48,6 @@ index 1456e89..e1da2da 100644
insert: jest.fn((diff) => Promise.reject(new Error('fake error'))),
fetchById: (id: string) => null,
deleteById: (id: string) => Promise.resolve(0),
extendLifetime: (id: string, noOfDays: number) => Promise.reject('random err'),
update: (diff: SharedDiff) => Promise.reject('random err'),
};
const action = new CreateSharedDiffAction(repo, metrics);
Expand Down Expand Up @@ -78,7 +76,6 @@ index 1456e89..e1da2da 100644
insert: jest.fn().mockReturnValueOnce(new Promise(() => {})),
fetchById: (id: string) => null,
deleteById: (id: string) => Promise.resolve(0),
extendLifetime: (id: string, noOfDays: number) => Promise.reject('random err'),
update: (diff: SharedDiff) => Promise.reject('random err'),
};
const action = new CreateSharedDiffAction(repo, metrics);
Expand Down
1 change: 0 additions & 1 deletion backend/tests/v2/DeleteSharedDiffAction.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ test('should create a DeleteSharedDiffAction and delete a SharedDiff by id', ()
insert: jest.fn(),
fetchById: jest.fn(),
deleteById: (id: string) => Promise.resolve(1),
extendLifetime: (id: string, noOfDays: number) => Promise.reject('random err'),
update: (diff: SharedDiff) => Promise.reject('random err'),
};
const action = new DeleteSharedDiffAction(repo, metrics);
Expand Down
13 changes: 11 additions & 2 deletions backend/tests/v2/ExtendLifetimeSharedDiffAction.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,11 @@ index 1456e89..e1da2da 100644
-a
+b
`
const DIFF = makeSharedDiff(raw_diff);
const repo: SharedDiffRepository = {
insert: jest.fn(),
fetchById: (id: string) => Promise.resolve({ id, ...makeSharedDiff(raw_diff) }),
fetchById: (id: string) => Promise.resolve({ id, ...DIFF }),
deleteById: (id: string) => Promise.resolve(0),
extendLifetime: (id: string, noOfDays: number) => Promise.reject('random err'),
update: (diff: SharedDiff) => Promise.resolve(diff),
};

Expand All @@ -31,3 +31,12 @@ test('should make a diff permanent', () => {
expect(diff.expiresAt.getFullYear()).toBe(9999);
});
});

test('should extend the diff lifetime', () => {
const spy = jest.spyOn(repo, "update");
const action = new ExtendLifetimeSharedDiffAction(repo, metrics);
return action.extendSharedDiffLifetime("1", 24).then(diff => {
expect(spy).toHaveBeenCalled();
expect(diff.expiresAt.getTime()).toBeGreaterThan(DIFF.expiresAt.getTime());
});
});
1 change: 0 additions & 1 deletion backend/tests/v2/GetSharedDiffAction.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ index 1456e89..e1da2da 100644
insert: jest.fn(),
fetchById: (id: string) => Promise.resolve({...makeSharedDiff(raw_diff), id}),
deleteById: (id: string) => Promise.resolve(0),
extendLifetime: (id: string, noOfDays: number) => Promise.reject('random err'),
update: (diff: SharedDiff) => Promise.reject('random err'),
};
const action = new GetSharedDiffAction(repo, metrics);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,27 +70,4 @@ describe('MongoSharedDiff tests', () => {
.then(stored_diff => repo.deleteById(stored_diff.id))
.then(deletedCount => expect(deletedCount).toEqual(1));
});

test('Mongo test: extend lifetime of a SharedDiff', () => {
const raw_diff = `
diff --git a/file.json b/file.json
index 1456e89..e1da2da 100644
--- a/file.json
+++ b/file.json
@@ -1,1 +1,1 @@
-a
+b
`
const shared_diff = makeSharedDiff(raw_diff);
const msPerDay = 24 * 60 * 60 * 1000;
return repo.insert(shared_diff)
.then((diff) => {
expect(diff.expiresAt.getTime() - diff.created.getTime()).toBeLessThan(2 * msPerDay);
return diff;
})
.then(stored_diff => repo.extendLifetime(stored_diff.id, 24))
.then(
(diff) => expect(diff.expiresAt.getTime() - diff.created.getTime())
.toBeGreaterThanOrEqual(2 * msPerDay));
});
});

0 comments on commit f6d28d4

Please sign in to comment.