error 1. "TypeError: Cannot read property 'debug' of undefined".
68 | }
69 |
> 70 | this._logger.debug(
| ^
71 | `Creating a ${
72 | createCacheControlDto.type
73 | } for site - ${siteId} with body - ${JSON.stringify(
error 2. TypeError: this._cacheControlModel is not a constructor
87 | };
88 |
> 89 | const cacheControlToCreate = new this._cacheControlModel({
| ^
90 | ...createCacheControlPayload
91 | });
92 |
I try to call the create method of service file. But getting error
Please Help to find the solution. Here I am placing the code. Please find it.
file 1. cache-control.service.spec.ts
import { getModelToken } from '@nestjs/mongoose';
import { Test, TestingModule } from '@nestjs/testing';
import { MongoMemoryServer } from 'mongodb-memory-server';
import { Connection, Model, connect } from 'mongoose';
import { CacheControlController } from './cache-control.controller';
import { CacheControlService } from './cache-control.service';
import { mockCacheControlService } from './mock/mock-cache-control.service';
import {
SearchAndProjectDto,
SearchDTO
} from '@classes/search-and-project-dto';
import { LABELS } from '@constants/labels.constant';
import { CacheControlStatus } from '@enums/cache-control-status.enum';
import { CacheControlType } from '@enums/cache-control-type.enum';
import { JmsCommandResponse } from '@interfaces/jms-command-response.interface';
import { JmsResponse } from '@interfaces/jms-response.interface';
import { PaginatedData } from '@interfaces/paginated-data.interface';
import { Injectable, Logger } from '@nestjs/common';
import { InjectModel } from '@nestjs/mongoose';
import { DbUtilService } from '@services/db-util.service';
import { ExceptionService } from '@services/exception.service';
import { JMSService } from '@services/jms.service';
import { LabelService } from '@services/label.service';
import { QueryService } from '@services/query.service';
import { SiteCommonService } from '@services/site-common.service';
import { SoftDeleteModel } from 'mongoose-delete';
import { JournalService } from '../journal/journal.service';
import { Site, SiteDocument, SiteSchema } from '../site/schemas/site.schema';
import {
CacheControl,
CacheControlSchema
} from './schemas/cache-control.schema';
import { EventEmitter2 } from '@nestjs/event-emitter';
import { FileUploadService } from '../file-upload/file-upload.service';
import {
Journal,
JournalDocument,
JournalSchema
} from '../journal/schemas/journal.schema';
import { ConfigService } from '@nestjs/config';
import { RetryService } from '@services/retry.service';
import {
FileUpload,
FileUploadSchema,
FileUploadDocument
} from '../file-upload/schema/file-upload.schema';
import { CreateCacheControlDTOStub } from './mock/create-cache-control.dto.stub';
describe('CacheControlService', () => {
let service: CacheControlService;
let mongod: MongoMemoryServer;
let mongoConnection: Connection;
let cacheControlModel: Model<CacheControl>;
let siteModel: Model<Site>;
let journalModel: Model<Journal>;
let fileUploadModel: Model<FileUpload>;
const mockRequest = <Request>{};
const mockCacheControlService = {};
const siteId = '62f134d689922f41a50095f7';
const cacheControlId = '63084113d836f908a66b0db4';
const accountId = '63084113d836f908a66b0db4';
// beforeEach(async () => {
beforeAll(async () => {
mongod = await MongoMemoryServer.create();
const uri = mongod.getUri();
mongoConnection = (await connect(uri)).connection;
cacheControlModel = mongoConnection.model(
'CacheControl',
CacheControlSchema
);
siteModel = mongoConnection.model('Site', SiteSchema);
// journalModel = mongoConnection.model('Journal', JournalSchema);
fileUploadModel = mongoConnection.model('FileUpload', FileUploadSchema);
// accountModel = mongoConnection.model('Account', AccountSchema);
const module: TestingModule = await Test.createTestingModule({
imports: [HttpModule],
controllers: [CacheControlController],
providers: [
CacheControlService,
SiteCommonService,
JournalService,
JMSService,
FileUploadService,
ConfigService,
EventEmitter2,
Logger,
// HttpService,
RetryService,
{
provide: getModelToken(CacheControl.name),
useValue: cacheControlModel
},
{ provide: getModelToken(Journal.name), useValue: journalModel },
{ provide: getModelToken(Site.name), useValue: siteModel },
{ provide: getModelToken(FileUpload.name), useValue: fileUploadModel },
{
provide: getModelToken(Journal.name),
useValue: jest.fn()
},
{
provide: getModelToken(CacheControl.name),
useValue: jest.fn()
}
]
})
// .useValue(mockCacheControlService)
.setLogger(new Logger(CacheControlService.name))
.compile();
service = module.get<CacheControlService>(CacheControlService);
});
afterAll(async () => {
await mongoConnection.dropDatabase();
await mongoConnection.close();
await mongod.stop();
});
afterEach(async () => {
const collections = mongoConnection.collections;
for (const key in collections) {
const collection = collections[key];
await collection.deleteMany({});
}
});
describe('CreateCacheControl', () => {
it('should create a Cache Control', async () => {
const createdCacheControl = await service.create(
accountId,
siteId,
CreateCacheControlDTOStub()
);
});
});
});
file 2. cache-control.service.ts
SearchAndProjectDto,
SearchDTO
} from '@classes/search-and-project-dto';
import { LABELS } from '@constants/labels.constant';
import { CacheControlStatus } from '@enums/cache-control-status.enum';
import { CacheControlType } from '@enums/cache-control-type.enum';
import { JmsCommandResponse } from '@interfaces/jms-command-response.interface';
import { JmsResponse } from '@interfaces/jms-response.interface';
import { PaginatedData } from '@interfaces/paginated-data.interface';
import { Injectable, Logger } from '@nestjs/common';
import { InjectModel } from '@nestjs/mongoose';
import { DbUtilService } from '@services/db-util.service';
import { ExceptionService } from '@services/exception.service';
import { JMSService } from '@services/jms.service';
import { LabelService } from '@services/label.service';
import { QueryService } from '@services/query.service';
import { SiteCommonService } from '@services/site-common.service';
import { SoftDeleteModel } from 'mongoose-delete';
import { JournalService } from '../journal/journal.service';
import { Site } from '../site/schemas/site.schema';
import {
CACHE_CONTROL_JOB_TYPE,
CACHE_CONTROL_JOURNAL_TYPE,
INVALIDATION_PATH_PATTERN_REGEX,
PURGE_PATH_PATTERN
} from './cache-control.constant';
import { CreateCacheControlDto } from './dto/create-cache-control.dto';
import {
CacheControl,
CacheControlDocument
} from './schemas/cache-control.schema';
import * as mongoose from 'mongoose';
import { CdnS3Bucket } from '../file-upload/file-upload.constant';
import { FileUploadService } from '../file-upload/file-upload.service';
import { CacheControlBulkUpload } from '@constants/event.constant';
import { PopulateService } from '@services/populate.service';
import * as crypto from 'crypto';
import { SegmentConfiguration } from '../segment-configuration/schemas/segment-configuration.schema';
@Injectable()
export class CacheControlService {
private readonly _logger = new Logger(CacheControlService.name);
constructor(
@InjectModel(CacheControl.name)
private readonly _cacheControlModel: SoftDeleteModel<CacheControlDocument>,
private readonly _siteCommonService: SiteCommonService,
private readonly _journalService: JournalService,
private readonly _jmsService: JMSService,
private readonly _fileUploadService: FileUploadService
) {}
async create(
accountId: string,
siteId: string,
createCacheControlDto: CreateCacheControlDto
): Promise<any> {
if (!createCacheControlDto.isBulkUpload) {
// Validating path pattern array
const isValidPathPattern = this._isValidPathPattern(
createCacheControlDto.pathPatterns,
createCacheControlDto.type
);
if (!isValidPathPattern) {
ExceptionService.badRequest('Invalid path pattern');
}
}
this._logger.debug(
`Creating a ${
createCacheControlDto.type
} for site - ${siteId} with body - ${JSON.stringify(
createCacheControlDto
)}`
);
const createCacheControlPayload = {
...createCacheControlDto,
siteId,
accountId,
status:
createCacheControlDto.type === CacheControlType.INVALIDATION &&
!createCacheControlDto?.isBulkUpload
? CacheControlStatus.COMPLETED
: CacheControlStatus.IN_PROGRESS
};
const cacheControlToCreate = new this._cacheControlModel({
...createCacheControlPayload
});
const createdCacheControl: CacheControl = await cacheControlToCreate.save();
switch (createCacheControlDto.type) {
case CacheControlType.INVALIDATION: {
// Journal the invalidation config change
this._journalService.createContext(
CACHE_CONTROL_JOURNAL_TYPE.invalidation
);
this._journalService.logCreateAction({
newValue: createdCacheControl
});
break;
}
case CacheControlType.PURGE: {
// Send command to JMS
// If bulk upload CSV, event will be fired to validate, process CSV and create Job in JMS
if (createdCacheControl.isBulkUpload) {
break;
}
// Getting site with segment configuration for token authentication
const site: Site = await this._getSiteWithSegmentConfigurations(siteId);
// Sign URL based on segment configuration's token auth
if (site.segmentConfigurations.length > 0) {
createCacheControlDto.pathPatterns = this._getSignedUrls(
createCacheControlDto.pathPatterns,
site.domainName,
site.segmentConfigurations
);
}
try {
const jmsJobId = await this._createAnCachePurgeJob(
createdCacheControl.id,
createCacheControlDto.pathPatterns,
site
);
// Updating Cache control with jmsJobId
await this.updateById(createdCacheControl._id, { jmsJobId });
} catch (exception) {
console.log(exception?.response?.statusText);
// Updating Cache control with FAILED status if we get error while creating job
await this.updateById(createdCacheControl._id, {
status: CacheControlStatus.FAILED,
message: 'Failed to create job, please try again'
});
}
break;
}
}
return createdCacheControl;
}
}
file 3. cache-control.controller.ts
import { CONTROLLER_VERSION_1 } from '@constants/api-version.constant';
import { CacheControlBulkUpload, EVENTS } from '@constants/event.constant';
import { CacheControlType } from '@enums/cache-control-type.enum';
import { JwtAuthGuard } from '@guards/jwt-auth.guard';
import { PaginatedData } from '@interfaces/paginated-data.interface';
import {
Body,
Controller,
Get,
HttpCode,
HttpStatus,
Param,
Post,
Query,
Req,
Request,
UploadedFile,
UseGuards,
UseInterceptors,
ValidationPipe
} from '@nestjs/common';
import { EventEmitter2 } from '@nestjs/event-emitter';
import { FileInterceptor } from '@nestjs/platform-express';
import { IdentifierPipe } from '@pipes/identifier.pipe';
import { ExceptionService } from '@services/exception.service';
import { SbJwtService } from '@services/sb-jwt.service';
import { isCSVFileformat } from '../bulk-upload-job/utils/csv-file-filter';
import {
CdnS3Bucket,
CdnS3FolderName,
FileUploadModuleType
} from '../file-upload/file-upload.constant';
import { FileUploadService } from '../file-upload/file-upload.service';
import { SITE_PARAMS } from '../site/site.constant';
import {
CACHE_CONTROL_PARAMS,
CACHE_CONTROL_ROUTES
} from './cache-control.constant';
import { CacheControlService } from './cache-control.service';
import { CreateCacheControlDto } from './dto/create-cache-control.dto';
import { CacheControl } from './schemas/cache-control.schema';
@UseGuards(JwtAuthGuard)
@Controller({
...CONTROLLER_VERSION_1,
path: `${CACHE_CONTROL_ROUTES.cacheControl_home}/${CACHE_CONTROL_ROUTES.cacheControl}/`
})
export class CacheControlController {
constructor(
private readonly _cacheControlService: CacheControlService,
private readonly _fileUploadService: FileUploadService,
private readonly eventEmitter: EventEmitter2
) {}
@Post()
@HttpCode(HttpStatus.CREATED)
async create(
@Request() request: Request,
@Param(SITE_PARAMS.siteId, new IdentifierPipe())
siteId: string,
@Body() body: CreateCacheControlDto
) {
const accountId = SbJwtService.getLoggedInAccountId(request);
return await this._cacheControlService.create(accountId, siteId, body);
}
}
file 4. cache-control.schema.ts
import { CacheControlType } from '@enums/cache-control-type.enum';
import { Prop, Schema, SchemaFactory } from '@nestjs/mongoose';
import * as mongoose from 'mongoose';
import { Document } from 'mongoose';
import { SoftDeleteDocument } from 'mongoose-delete';
import { Site } from 'src/modules/site/schemas/site.schema';
export type CacheControlDocument = CacheControl & Document & SoftDeleteDocument;
@Schema({
collection: 'cacheControls',
timestamps: true
})
export class CacheControl extends Document {
@Prop({
type: mongoose.Schema.Types.String,
required: false
})
title: string;
@Prop({
type: mongoose.Schema.Types.ObjectId,
required: true,
ref: 'accounts'
})
accountId: string;
@Prop({
type: mongoose.Schema.Types.ObjectId,
required: true,
ref: 'sites'
})
siteId: string;
@Prop({
type: mongoose.Schema.Types.ObjectId
})
jmsJobId?: string;
@Prop({
type: mongoose.Schema.Types.Array,
required: true,
minlength: 1
})
pathPatterns: string[];
@Prop({
type: mongoose.Schema.Types.String,
enum: Object.values(CacheControlStatus),
required: true
})
status: CacheControlStatus;
@Prop({
type: mongoose.Schema.Types.String,
required: false
})
message?: string;
@Prop({
type: mongoose.Schema.Types.String,
enum: Object.values(CacheControlType),
required: true
})
type: CacheControlType;
@Prop({
type: mongoose.Schema.Types.Boolean,
required: true,
default: false
})
isBulkUpload: boolean;
@Prop({
type: mongoose.Schema.Types.String,
required: false
})
fileName: string;
@Prop({
type: mongoose.Schema.Types.String,
required: false
})
fileLink: string;
@Prop({
type: mongoose.Schema.Types.String,
required: false
})
fileKey: string;
@Prop({
type: mongoose.Schema.Types.String,
required: false
})
commandId: string;
site: Site;
}
export const CacheControlSchema = SchemaFactory.createForClass(CacheControl);
CacheControlSchema.virtual('site', {
ref: 'Site',
localField: 'siteId',
foreignField: '_id',
justOne: true
});