-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #43 from ConductionNL/feature/EGISTERS-40/object-a…
…udit-trails object audit trails
- Loading branch information
Showing
12 changed files
with
364 additions
and
89 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
import { AuditTrail } from './auditTrail' | ||
import { TAuditTrail } from './auditTrail.types' | ||
|
||
export const mockAuditTrailData = (): TAuditTrail[] => [ | ||
{ | ||
id: '1234a1e5-b54d-43ad-abd1-4b5bff5fcd3f', | ||
uuid: 'uuid-1234a1e5-b54d-43ad-abd1-4b5bff5fcd3f', | ||
schema: 1, | ||
register: 1, | ||
object: 1, | ||
action: 'create', | ||
changed: JSON.stringify({ key: 'value' }), | ||
user: 'user1', | ||
userName: 'User One', | ||
session: 'session1', | ||
request: 'request1', | ||
ipAddress: '127.0.0.1', | ||
version: '1.0', | ||
created: new Date().toISOString(), | ||
}, | ||
{ | ||
id: '5678a1e5-b54d-43ad-abd1-4b5bff5fcd3f', | ||
uuid: 'uuid-5678a1e5-b54d-43ad-abd1-4b5bff5fcd3f', | ||
schema: 2, | ||
register: 2, | ||
object: 2, | ||
action: 'update', | ||
changed: JSON.stringify({ key: 'value' }), | ||
user: 'user2', | ||
userName: 'User Two', | ||
session: 'session2', | ||
request: 'request2', | ||
ipAddress: '127.0.0.2', | ||
version: '1.1', | ||
created: new Date().toISOString(), | ||
}, | ||
] | ||
|
||
export const mockAuditTrail = (data: TAuditTrail[] = mockAuditTrailData()): TAuditTrail[] => data.map(item => new AuditTrail(item)) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
/* eslint-disable @typescript-eslint/no-explicit-any */ | ||
import { AuditTrail } from './auditTrail' | ||
import { mockAuditTrailData } from './auditTrail.mock' | ||
|
||
describe('AuditTrail Entity', () => { | ||
it('should create an AuditTrail entity with full data', () => { | ||
const auditTrail = new AuditTrail(mockAuditTrailData()[0]) | ||
|
||
expect(auditTrail).toBeInstanceOf(AuditTrail) | ||
expect(auditTrail).toEqual(mockAuditTrailData()[0]) | ||
expect(auditTrail.validate().success).toBe(true) | ||
}) | ||
|
||
it('should create an AuditTrail entity with partial data', () => { | ||
const auditTrail = new AuditTrail(mockAuditTrailData()[0]) | ||
|
||
expect(auditTrail).toBeInstanceOf(AuditTrail) | ||
expect(auditTrail.id).toBe(null) | ||
expect(auditTrail.uuid).toBe(mockAuditTrailData()[0].uuid) | ||
expect(auditTrail.register).toBe(mockAuditTrailData()[0].register) | ||
expect(auditTrail.schema).toBe(mockAuditTrailData()[0].schema) | ||
expect(auditTrail.object).toBe(mockAuditTrailData()[0].object) | ||
expect(auditTrail.action).toBe(mockAuditTrailData()[0].action) | ||
expect(auditTrail.changed).toBe(mockAuditTrailData()[0].changed) | ||
expect(auditTrail.user).toBe(mockAuditTrailData()[0].user) | ||
expect(auditTrail.userName).toBe(mockAuditTrailData()[0].userName) | ||
expect(auditTrail.session).toBe(mockAuditTrailData()[0].session) | ||
expect(auditTrail.request).toBe(mockAuditTrailData()[0].request) | ||
expect(auditTrail.ipAddress).toBe(mockAuditTrailData()[0].ipAddress) | ||
expect(auditTrail.version).toBe(mockAuditTrailData()[0].version) | ||
expect(auditTrail.created).toBe(mockAuditTrailData()[0].created) | ||
expect(auditTrail.validate().success).toBe(true) | ||
}) | ||
|
||
it('should fail validation with invalid data', () => { | ||
const auditTrail = new AuditTrail(mockAuditTrailData()[1]) | ||
|
||
expect(auditTrail).toBeInstanceOf(AuditTrail) | ||
expect(auditTrail.validate().success).toBe(false) | ||
expect(auditTrail.validate().error?.issues).toContainEqual(expect.objectContaining({ | ||
path: ['id'], | ||
message: 'Expected string, received null', | ||
})) | ||
}) | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
import { SafeParseReturnType, z } from 'zod' | ||
import { TAuditTrail } from './auditTrail.types' | ||
|
||
export class AuditTrail implements TAuditTrail { | ||
|
||
public id: string | ||
public uuid: string | ||
public schema: number | ||
public register: number | ||
public object: number | ||
public action: string | ||
public changed: string | ||
public user: string | ||
public userName: string | ||
public session: string | ||
public request: string | ||
public ipAddress: string | ||
public version: string | ||
public created: string | ||
|
||
constructor(auditTrail: TAuditTrail) { | ||
this.id = auditTrail.id || null | ||
this.uuid = auditTrail.uuid || null | ||
this.schema = auditTrail.schema || 0 | ||
this.register = auditTrail.register || 0 | ||
this.object = auditTrail.object || 0 | ||
this.action = auditTrail.action || '' | ||
this.changed = auditTrail.changed || '' | ||
this.user = auditTrail.user || '' | ||
this.userName = auditTrail.userName || '' | ||
this.session = auditTrail.session || '' | ||
this.request = auditTrail.request || '' | ||
this.ipAddress = auditTrail.ipAddress || '' | ||
this.version = auditTrail.version || '' | ||
this.created = auditTrail.created || '' | ||
} | ||
|
||
public validate(): SafeParseReturnType<TAuditTrail, unknown> { | ||
const schema = z.object({ | ||
id: z.string().nullable(), | ||
uuid: z.string().uuid().nullable(), | ||
schema: z.number(), | ||
register: z.number(), | ||
object: z.number(), | ||
action: z.string(), | ||
changed: z.string(), | ||
user: z.string(), | ||
userName: z.string(), | ||
session: z.string(), | ||
request: z.string(), | ||
ipAddress: z.string(), | ||
version: z.string(), | ||
created: z.string(), | ||
}) | ||
|
||
return schema.safeParse(this) | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
export type TAuditTrail = { | ||
id: string | ||
uuid: string | ||
schema: number // schema ID | ||
register: number // register ID | ||
object: number // object ID | ||
action: string | ||
changed: string // JSON object | ||
user: string | ||
userName: string | ||
session: string | ||
request: string | ||
ipAddress: string | ||
version: string | ||
created: string | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
export * from './auditTrail.ts' | ||
export * from './auditTrail.types.ts' | ||
export * from './auditTrail.mock.ts' | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,102 @@ | ||
<script setup> | ||
import { objectStore, navigationStore } from '../../store/store.js' | ||
</script> | ||
|
||
<template> | ||
<NcModal label-id="View Object Audit Trail modal" | ||
@close="closeDialog"> | ||
<div class="modal__content"> | ||
<div class="audit-item"> | ||
<h3>Audit Trail ID: {{ auditTrail.id }}</h3> | ||
|
||
<p><strong>Action:</strong> {{ auditTrail.action }}</p> | ||
<p><strong>User:</strong> {{ auditTrail.userName }} ({{ auditTrail.user }})</p> | ||
<p><strong>Session:</strong> {{ auditTrail.session }}</p> | ||
<p><strong>IP Address:</strong> {{ auditTrail.ipAddress }}</p> | ||
<p><strong>Created:</strong> {{ new Date(auditTrail.created).toLocaleString() }}</p> | ||
|
||
<div v-if="auditTrail.changed"> | ||
<h4>Changes:</h4> | ||
<ul> | ||
<li v-for="(change, key) in auditTrail.changed" :key="key"> | ||
<strong>{{ key }}:</strong><br> | ||
<span>Old: {{ change.old ?? 'N/A' }}</span><br> | ||
<span>New: {{ change.new ?? 'N/A' }}</span> | ||
</li> | ||
</ul> | ||
</div> | ||
|
||
<div class="navigation-buttons"> | ||
<NcButton> | ||
Go to linked Schema | ||
</NcButton> | ||
<NcButton> | ||
Go to linked Register | ||
</NcButton> | ||
<NcButton> | ||
Go to linked Object | ||
</NcButton> | ||
</div> | ||
</div> | ||
|
||
<NcButton @click="closeDialog"> | ||
<template #icon> | ||
<Cancel :size="20" /> | ||
</template> | ||
Close | ||
</NcButton> | ||
</div> | ||
</NcModal> | ||
</template> | ||
|
||
<script> | ||
import { | ||
NcModal, | ||
NcButton, | ||
} from '@nextcloud/vue' | ||
import Cancel from 'vue-material-design-icons/Cancel.vue' | ||
export default { | ||
name: 'ViewObjectAuditTrail', | ||
components: { | ||
NcModal, | ||
NcButton, | ||
Cancel, | ||
}, | ||
data() { | ||
return { | ||
auditTrail: {}, // Initialize with an empty object | ||
} | ||
}, | ||
mounted() { | ||
// Assuming objectStore.auditTrailItem is a single audit trail object | ||
this.auditTrail = objectStore.auditTrailItem || {} | ||
}, | ||
methods: { | ||
closeDialog() { | ||
navigationStore.setModal(null) | ||
objectStore.setAuditTrailItem(null) | ||
}, | ||
}, | ||
} | ||
</script> | ||
|
||
<style scoped> | ||
.modal__content { | ||
margin: 0.8rem; | ||
} | ||
.audit-item { | ||
border-bottom: 1px solid #ccc; | ||
padding: 0 0 10px 0; | ||
margin: 0 0 10px 0; | ||
} | ||
.navigation-buttons { | ||
margin-top: 10px; | ||
display: flex; | ||
gap: 10px; | ||
justify-content: center; | ||
} | ||
</style> |
Oops, something went wrong.