Nest.js can't resolve the dependencies of CacheConfigService - javascript

I want to use the CacheModule in the AuthModule and I have written this code but still getting the error in the console:
The Auth.module.ts file in which I want to import the cache module:
#Module({
providers: [CacheConfigService, SupertokensService],
exports: [],
imports: [CacheConfigModule, UsersModule],
controllers: [],
})
export class AuthModule implements NestModule {
configure(consumer: MiddlewareConsumer) {
consumer.apply(AuthMiddleware).forRoutes('*');
}
static forRoot({
connectionURI,
apiKey,
appInfo,
}: AuthModuleConfig): DynamicModule {
return {
// providers and exports
imports: [CacheConfigModule],
};
}
}
The cache config.module.ts file code. The cache config.service.ts file contains the logic:
#Module({
providers: [CacheConfigService],
exports: [CacheConfigService],
imports: [
CacheModule.register<RedisClientOptions>({
isGlobal: true,
// store: redisStore,
url: 'redis://' + process.env.REDIS_HOST + ':' + process.env.REDIS_PORT,
}),
],
})
export class CacheConfigModule {}
I want to use the cache service in the following class:
#Injectable()
export class SupertokensService {
private redisClient = redis.createClient({
url: this.cacheConfigService.url,
});
constructor(
#Inject(forwardRef(() => UsersService)) private userService: UsersService,
private cacheConfigService: CacheConfigService
) {
supertokens.init({
appInfo: this.config.appInfo,
supertokens: {
connectionURI: this.config.connectionURI,
apiKey: this.config.apiKey,
},
recipeList: [
ThirdPartyEmailPassword.init({
providers: [
ThirdPartyEmailPassword.Google({
clientSecret: 'TODO: GOOGLE_CLIENT_SECRET',
clientId:
'CLIENT_ID',
}),
],
signUpFeature: {
...signup logic
},
override: {
apis: (originalImplementation: any) => {
return {
...originalImplementation,
emailPasswordSignInPOST: async (input: any) => {
if (
originalImplementation.emailPasswordSignInPOST === undefined
) {
throw Error('Should never come here');
}
let response: any =
await originalImplementation.emailPasswordSignInPOST(input);
// retrieving the input from body logic
const { email } = inputObject;
const user = await this.userService.findOneByEmail(email);
const id = user?.id;
const token = jwt.sign({email, id}, 'mysecret';, {
expiresIn: '2h',
});
response.token = token;
await this.redisClient.set("Token", token, {
EX: 60 * 60 * 24,
});
return response;
},
};
},
},
}),
],
});
}
}

The error has been thrown because you have used ConfigService in CacheConfigService, but it has never been imported into CacheConfigModule.
If you want to have ConfigService then you must import it into AppModule, as well as CacheConfigModule.
app.module.ts:
import { ConfigModule } from '#nestjs/config';
import configuration from './config/configuration'; // or wherever your config file exists
#Module({
imports: [
ConfigModule.forRoot({
load: [configuration],
}),
// rest of code
],
// rest of code
})
export class AppModule {}
config.module.ts:
import { ConfigModule } from '#nestjs/config';
#Module({
providers: [CacheConfigService],
exports: [CacheConfigService],
imports: [
CacheModule.register<RedisClientOptions>({
isGlobal: true,
// store: redisStore,
url: 'redis://' + process.env.REDIS_HOST + ':' + process.env.REDIS_PORT,
}),
ConfigModule,
],
})
export class CacheConfigModule {}

Related

Cannot test e2e because Nestjs doesn't resolve dependencies

I have the following error :
Nest can't resolve dependencies of the ParametrageRepository (?). Please make sure that the argument DataSource at index [0] is available in the TypeOrmModule context.
My test code :
describe("ParametrageController (e2e)", () => {
let parametrage: INestApplication;
beforeEach(async () => {
const moduleFixture: TestingModule = await Test.createTestingModule({
imports: [ParametrageModule],
}).compile();
parametrage = moduleFixture.createNestApplication();
await parametrage.init();
});
it("/ (POST)", () =>
request(parametrage.getHttpServer())
.post("/parametrage")
.send({
libelle: "GROUPE_TYPE",
liste: ["TEAM", "SERVICE", "ORGANISATION"],
})
.expect(201));
});
My module code:
#Module({
imports: [TypeOrmModule.forFeature([Parametrage])],
exports: [TypeOrmModule],
controllers: [ParametrageController],
providers: [ParametrageService, ParametrageRepository, ParametrageActions, Logger],
})
export class ParametrageModule {}
I cannot tel why I have this error since I followed the Nestjs documentation. Maybe I skipped a part I don't know. Maybe it's because of my providers that has parameters in their constructors :
My ParametrageRepository provider :
#Injectable()
export class ParametrageRepository
extends RepositoryStarter<Parametrage, IParametrageListFilter>
implements IParametrageRepository
{
constructor(#InjectDataSource() datasource: DataSource) {
super(datasource.getRepository(Parametrage));
}
I tried to add providers injection :
const moduleFixture: TestingModule = await Test.createTestingModule({
imports: [ParametrageModule],
** providers: [
{ provide: ParametrageActions, useValue: ParametrageActions },
{ provide: ParametrageRepository, useValue: ParametrageRepository },
{ provide: Logger, useValue: Logger ,
],**
}).compile();
But stil the same error, it didn't solved anything
Thanks in advance

NestJs Testing with CACHE_MANAGER injected

I have some service in which I inject the CACHE_MANAGER in the constructor
import { CACHE_MANAGER, Inject, Injectable } from '#nestjs/common';
import { Cache } from 'cache-manager';
...
export class ManagerService {
constructor(#Inject(CACHE_MANAGER) private cacheManager: Cache) {}
...
}
That gives me an error when I test the modules the import those service
Nest can't resolve dependencies of the ManagerService (?). Please make sure that the argument CACHE_MANAGER at index [0] is available in the Web3ManagerService context.
I'm relatively new to NestJs so I really cannot figure out how to solve it
To inject the cache manager provider under the CACHE_MANAGER, you need to import the nestjs module that creates this provider into the module that has the ManagerService
#Module({
imports: [CacheModule.register()], // <<<<
providers: [ManagerService],
})
export class AppModule {}
like the docs shows https://docs.nestjs.com/techniques/caching
I just had the same problem and resolved it this way:
manager.service.spec.ts
beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
providers: [ManagerService, { provide: CACHE_MANAGER, useValue: {} }],
}).compile();
service = module.get<ManagerService>(ManagerService);
});
Set isGlobal: true:
CacheModule.register({
url: process.env.REDIS_URL,
db: 0,
port: parseInt(process.env.REDIS_PORT),
password: process.env.REDIS_PASSWORD,
isGlobal: true, //<<<<<<<
})

Keycloak - how to disable sharing session between two (Angular) client apps?

I have two angular client applications that use Keycloak's angular client for authentication. The problem is, that when i log in on one of them, i'm automatically being logged to another one. I have separate client for each one though.
Keycloak service initialization looks like this in both apps:
#NgModule({
declarations: [AppComponent],
imports: [
AppRoutingModule,
BrowserModule,
KeycloakAngularModule
],
providers: [KeycloakService],
entryComponents: [AppComponent]
})
export class AppModule implements DoBootstrap {
constructor(private keycloakService: KeycloakService) {
}
ngDoBootstrap(app: ApplicationRef) {
this.keycloakService
.init({config: environment.keycloak, initOptions: {onLoad: 'login-required'}})
.then(() => app.bootstrap(AppComponent));
}
}
Keycloak config for the first app:
const keycloakConfig: KeycloakConfig = {
realm: 'quick',
url: 'http://localhost:8000/auth',
clientId: 'quick-ui-customer'
};
export const environment = {
production: false,
keycloak: keycloakConfig,
};
And for the second one:
const keycloakConfig: KeycloakConfig = {
realm: 'quick',
url: 'http://localhost:8000/auth',
clientId: 'quick-ui-employee'
};
export const environment = {
production: false,
keycloak: keycloakConfig,
};
That is a core feature of Single Sign On protocol. But if you don't want to share session, then create clients in different realms.

Angular 4, Error: Can't resolve all parameters for StateObservable: (?)

i am writing unit test on one of my service. I am keep getting Error: Can't resolve all parameters for StateObservable: (?). and my test is failing.
can anyone tell me what is the issue?
spec file code
fdescribe("Physician Service", () => {
let physicianService: PhysicianService;
let httpTestingController: HttpTestingController;
let backend: MockBackend;
let initialResponse: any;
beforeEach(() => {
TestBed.configureTestingModule({
imports: [
HttpClientTestingModule
],
providers: [
Http,
ConnectionBackend,
UtilService,
StateObservable,
RouterModule,
SessionService,
HttpClientTestingModule,
BaseRequestOptions,
MockBackend,
PhysicianService,
AuthService,
BrowserXhr,
XHRBackend,
Store,
{
deps: [
MockBackend,
BaseRequestOptions
],
provide: Http,
useFactory: (backend: MockBackend, defaultOptions: BaseRequestOptions) => {
return new Http(backend, defaultOptions);
}
}
],
schemas:[
NO_ERRORS_SCHEMA
]
});
});
fit("Should Create Physicians Service",
inject([PhysicianService], (physicianService: PhysicianService) => {
expect(physicianService).toBeTruthy();
}));
});
can anyone help me in this regard
Thanks
This should have an actual answer instead of being in the comments.
In the TestBed.configureTestingModule imports add StoreModule.forRoot({})
TestBed.configureTestingModule({
imports: [
...
StoreModule.forRoot({})
],
providers: [
...
]
});

Override environment variables in jasmine test

I have a Angular service that looks something like this:
import {environment} from '../environment'
....
public something() {
if(environment.production)
{
// do stuf
} else {
// do something else
}
}
Now i want to test both cases (dev and prod environemnt). How do I "mock" when the environment is imported ?
So i came up with a solution where I didn't have to check for the environment in my service:
I used the useFactory:
NgModule({
declarations: [],
imports: [],
providers: [
{
provide: Service,
useFactory: (httpClient: HttpClient) => {
if (environment.production) {
return new MyCustomService(httpClient);
} else {
return new Service();
}
},
deps: [HttpClient],
}
],
bootstrap: [AppComponent]
})
This way i manage which service is provided when the application is started up

Categories

Resources