@ -0,0 +1,23 @@
|
|||||||
|
import { Catch, ExceptionFilter } from '@nestjs/common';
|
||||||
|
|
||||||
|
import {
|
||||||
|
AuditException,
|
||||||
|
AuditExceptionCode,
|
||||||
|
} from 'src/engine/core-modules/audit/audit.exception';
|
||||||
|
import { UserInputError } from 'src/engine/core-modules/graphql/utils/graphql-errors.util';
|
||||||
|
|
||||||
|
@Catch(AuditException)
|
||||||
|
export class AuditExceptionFilter implements ExceptionFilter {
|
||||||
|
catch(exception: AuditException) {
|
||||||
|
switch (exception.code) {
|
||||||
|
case AuditExceptionCode.INVALID_TYPE:
|
||||||
|
case AuditExceptionCode.INVALID_INPUT:
|
||||||
|
throw new UserInputError(exception.message);
|
||||||
|
default: {
|
||||||
|
const _exhaustiveCheck: never = exception.code;
|
||||||
|
|
||||||
|
throw exception;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,6 +1,7 @@
|
|||||||
import { CustomException } from 'src/utils/custom-exception';
|
import { CustomException } from 'src/utils/custom-exception';
|
||||||
|
|
||||||
export class AuditException extends CustomException {
|
export class AuditException extends CustomException {
|
||||||
|
declare code: AuditExceptionCode;
|
||||||
constructor(message: string, code: AuditExceptionCode) {
|
constructor(message: string, code: AuditExceptionCode) {
|
||||||
super(message, code);
|
super(message, code);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,5 +1,7 @@
|
|||||||
|
import { UseFilters } from '@nestjs/common';
|
||||||
import { Args, Mutation, Resolver } from '@nestjs/graphql';
|
import { Args, Mutation, Resolver } from '@nestjs/graphql';
|
||||||
|
|
||||||
|
import { AuditExceptionFilter } from 'src/engine/core-modules/audit/audit-exception-filter';
|
||||||
import {
|
import {
|
||||||
AuditException,
|
AuditException,
|
||||||
AuditExceptionCode,
|
AuditExceptionCode,
|
||||||
@ -19,6 +21,7 @@ import { Analytics } from './entities/analytics.entity';
|
|||||||
import { AuditService } from './services/audit.service';
|
import { AuditService } from './services/audit.service';
|
||||||
|
|
||||||
@Resolver(() => Analytics)
|
@Resolver(() => Analytics)
|
||||||
|
@UseFilters(AuditExceptionFilter)
|
||||||
export class AuditResolver {
|
export class AuditResolver {
|
||||||
constructor(private readonly auditService: AuditService) {}
|
constructor(private readonly auditService: AuditService) {}
|
||||||
|
|
||||||
|
|||||||
@ -0,0 +1,53 @@
|
|||||||
|
import { makePageview } from './analytics.utils';
|
||||||
|
|
||||||
|
describe('makePageview', () => {
|
||||||
|
it('should create a pageview with default properties when none are provided', () => {
|
||||||
|
const result = makePageview('test-page');
|
||||||
|
|
||||||
|
expect(result.name).toBe('test-page');
|
||||||
|
expect(result.type).toBe('page');
|
||||||
|
expect(result.properties).toEqual({
|
||||||
|
href: '',
|
||||||
|
locale: '',
|
||||||
|
pathname: '',
|
||||||
|
referrer: '',
|
||||||
|
sessionId: '',
|
||||||
|
timeZone: '',
|
||||||
|
userAgent: '',
|
||||||
|
});
|
||||||
|
expect(result.timestamp).toBeDefined();
|
||||||
|
expect(result.version).toBe('1');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create a pageview with provided properties and fill in defaults for missing ones', () => {
|
||||||
|
const providedProperties = {
|
||||||
|
href: 'https://example.com',
|
||||||
|
sessionId: 'test-session-id',
|
||||||
|
};
|
||||||
|
|
||||||
|
const result = makePageview('test-page', providedProperties);
|
||||||
|
|
||||||
|
expect(result.name).toBe('test-page');
|
||||||
|
expect(result.type).toBe('page');
|
||||||
|
expect(result.properties).toEqual({
|
||||||
|
href: 'https://example.com',
|
||||||
|
locale: '',
|
||||||
|
pathname: '',
|
||||||
|
referrer: '',
|
||||||
|
sessionId: 'test-session-id',
|
||||||
|
timeZone: '',
|
||||||
|
userAgent: '',
|
||||||
|
});
|
||||||
|
expect(result.timestamp).toBeDefined();
|
||||||
|
expect(result.version).toBe('1');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should handle empty properties object', () => {
|
||||||
|
const result = makePageview('test-page', {});
|
||||||
|
|
||||||
|
expect(result.name).toBe('test-page');
|
||||||
|
expect(result.type).toBe('page');
|
||||||
|
expect(result.properties.sessionId).toBe('');
|
||||||
|
expect(result.properties.href).toBe('');
|
||||||
|
});
|
||||||
|
});
|
||||||
@ -6,13 +6,13 @@ export const pageviewSchema = baseEventSchema.extend({
|
|||||||
type: z.literal('page'),
|
type: z.literal('page'),
|
||||||
name: z.string(),
|
name: z.string(),
|
||||||
properties: z.object({
|
properties: z.object({
|
||||||
href: z.string(),
|
href: z.string().optional().default(''),
|
||||||
locale: z.string(),
|
locale: z.string().optional().default(''),
|
||||||
pathname: z.string(),
|
pathname: z.string().optional().default(''),
|
||||||
referrer: z.string(),
|
referrer: z.string().optional().default(''),
|
||||||
sessionId: z.string(),
|
sessionId: z.string().optional().default(''),
|
||||||
timeZone: z.string(),
|
timeZone: z.string().optional().default(''),
|
||||||
userAgent: z.string(),
|
userAgent: z.string().optional().default(''),
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user