Skip to content

Commit

Permalink
fix(easy): Improve creation of Audit and check for valid Identity.
Browse files Browse the repository at this point in the history
Check should also happen on creation of Audit from json, however this would mess up existing Audits where only the 'when' is filled
  • Loading branch information
woutervanbakel committed Jul 3, 2024
1 parent 99d7fab commit a38f24b
Show file tree
Hide file tree
Showing 3 changed files with 66 additions and 7 deletions.
15 changes: 9 additions & 6 deletions packages/easy/src/domain/Audit.ts
Original file line number Diff line number Diff line change
@@ -1,20 +1,23 @@
import { Struct } from './Struct';
import { choose, ctx, Id, Json } from '../types';
import { choose, ctx, Identity, isIdentity, Json } from '../types';
import { required, valid } from '../validation';
import { DateTime } from './values';

export class Audit extends Struct {
@required() readonly by: { id: Id; user: string } = { id: this.state.by.id, user: this.state.by.user };
@required() readonly by: Identity = { id: this.state.by?.id, user: this.state.by?.user };
@valid() readonly when: DateTime = new DateTime(this.state.when);

constructor(json?: Json) {
super(
choose(json)
.is.defined(
j => j,
j => j
)
.else({ by: ctx.request?.identity ?? { id: 0, user: 'easy' }, when: DateTime.now.toJSON() })
j => j,
j => j,
)
.else({
by: isIdentity(ctx.request?.identity) ? ctx.request?.identity : { id: 0, user: 'easy' },
when: DateTime.now.toJSON(),
}),
);
}
}
5 changes: 4 additions & 1 deletion packages/easy/src/types/Is.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { Constructor } from './Constructor';
import { Constructor, use } from './Constructor';
import { Identity } from './Identity';

export const isDefined = <T = unknown>(o?: T): o is NonNullable<T> => o !== undefined && o !== null;

Expand Down Expand Up @@ -35,6 +36,8 @@ export const isIntersecting = (o?: unknown[], values?: unknown[]): boolean => is

export const isError = (e: unknown): e is Error => isDefined(e) && e instanceof Error;

export const isIdentity = (by: unknown): by is Identity => use(by as Identity, b => isObject(b) && isDefined(b.id));

export const isNotPresent = (...os: unknown[]): boolean =>
os.some(
o =>
Expand Down
53 changes: 53 additions & 0 deletions packages/easy/test/domain/Audit.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import '@thisisagile/easy-test';
import { Audit, ctx, DateTime } from '../../src';
import { mock } from '@thisisagile/easy-test';

describe('Audit', () => {
const by = { id: '42', user: 'john.dear@dmark.com' };
const when = '2021-05-03T10:31:24.000Z';

test('construct', () => {
const a = new Audit({ by, when });
expect(a).toBeValid();
expect(a.by.id).toBe(by.id);
expect(a.by.user).toBe(by.user);
expect(a.when.toString()).toBe(when);
});

test('construct from empty', () => {
mock.property(DateTime, 'now', new DateTime(when));

const a = new Audit();
expect(a).toBeValid();
expect(a.by.id).toBe(0);
expect(a.by.user).toBe('easy');
expect(a.when.toString()).toBe(when);
});

test('construct from empty object defaults to easy', () => {
const a = new Audit({});
expect(a).not.toBeValid();
});

test.each([
[{ by: { id: '42' } }],
[{ by: { user: 'email' } }],
[{ by: {} }],
[{ by: undefined }],
])('construct from invalid request identity by %j defaults to easy', (by) => {
mock.property(ctx.request, 'identity', by as any);
const a = new Audit();
expect(a).toBeValid();
expect(a.by.id).toBe(0);
expect(a.by.user).toBe('easy');
});

test('construct from valid request identity', () => {
mock.property(ctx.request, 'identity', { ...by } as any);

const a = new Audit();
expect(a).toBeValid();
expect(a.by).toEqual(by);
expect(a.when).toBeInstanceOf(DateTime);
});
});

0 comments on commit a38f24b

Please sign in to comment.