Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat/test for provider #49

Merged
merged 2 commits into from
Jan 4, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 43 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ We need to build a Video service so users can share there videos with others, bu

2. Next let's use `AccessControlModule` in our Root module:

```ts
```ts
// app.module.ts

import { roles } from './app.roles';
Expand All @@ -101,8 +101,9 @@ We need to build a Video service so users can share there videos with others, bu

Until now everything is fine, but let's make our application,
assume that we have list of video names, user can - _according to our roles_ - `create:own` new video, and `read:any` video, so let's build it:
```

```ts
```ts
// app.controller.ts
...
@Controller()
Expand All @@ -119,9 +120,47 @@ We need to build a Video service so users can share there videos with others, bu
return this.appService.root(userRoles);
}
}
```
```

### ForRootAsync

Injecting providers for a RoleBuilder Factory (using a database to populate roles)

```ts
@Injectable()
class RoleProvider {

getRoles(): Promise<string[]> {
return Promise.resolve([
'my-custom-role',
]);
}
}

@Module({
providers: [RoleProvider],
exports: [RoleProvider],
})
class RoleModule {

}

@Module({
imports: [
AccessControlModule.forRootAsync({
imports: [TestModule],
inject: [RoleService],
useFactory: async (roleService: RoleService): Promise<RolesBuilder> => {
return new RolesBuilder(await roleService.getRoles());
},
}),
],
})
export class AccessModule {}
```
Notice the use of `imports` in the forRootAsync method. This will allow you to inject exported providers from the imported module. Injecting providers, provided in the same module as the imported AccessControlModule will result in the provider not being found. This is because the module is created before the providers.

So let's discuss what's going on!
So let's discuss what's going on!

First we introduced two new decorators, actually they are three, but let's see what they can do:

Expand Down
33 changes: 33 additions & 0 deletions src/access-control.module.async.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {ROLES_BUILDER_TOKEN} from './constants';
import { delay } from 'rxjs/operators';
import { GrantsController } from './grants.controller';
import { ACOptions } from './ac-options.interface';
import { Injectable, Module } from '@nestjs/common';

describe('forRootAsync', () => {
it('Can instance with provider method', async () => {
Expand Down Expand Up @@ -39,6 +40,38 @@ describe('forRootAsync', () => {

expect(roles).toBeInstanceOf(RolesBuilder);
});

it('Can inject a provider', async () => {

@Injectable()
class TestProvider {
}

@Module({
providers: [TestProvider],
exports: [TestProvider],
})
class TestModule {

}

const module: TestingModule = await Test.createTestingModule({
imports: [
AccessControlModule.forRootAsync({
imports: [TestModule],
inject: [TestProvider],
useFactory: (test: TestProvider): RolesBuilder => {
expect(test).toBeInstanceOf(TestProvider);
return new RolesBuilder();
},
}),
],
}).compile();

const roles = module.get(ROLES_BUILDER_TOKEN);

expect(roles).toBeInstanceOf(RolesBuilder);
});
});

describe('forRoles', () => {
Expand Down