OktaAuthModule Not Resolving Correctly When Using Factory for Config (okta-angular and okta-auth.js)

Hi Alisa,

As per custService is concern, it simple grabs access token from okta and calls a http request and returns an observable.

We are not using OktaAuthStateService to get the state of login and logout. We are using SSO.

custService.ts

export class CService {

  constructor(private http: HttpClient,
    @Inject(OKTA_AUTH) private oktaAuth: OktaAuth) {}

  getStore(storeId: number): Observable<StoreDealer> {
    return from(
      this.oktaAuth.getAccessToken()).pipe(
      switchMap(accessToken => {
        let url = `${environment.storeBaseUrl}/cust/dealer/${encodeURIComponent(storeId)}`;
        const options = {
          headers: {
            'Authorization': accessToken
          }
        };
        return this.http.get<StoreDealer>(url, options).pipe(catchError(error => throwError(error)));
      })
    );
  }

I have to write a test case for this.
custService.spec.ts

describe('CustService', () => {
  let httpClientSpy: jasmine.SpyObj<HttpClient>;

//As per last message
  const authServiceSpy = jasmine.createSpyObj<OktaAuth>(['getAccessToken']);

  // const oktaConfig = {
  //   issuer: 'http://someissuerLink.com',
  //   clientId: 'clientId',
  //   redirectUri: 'http://localhost:4200/callback'
  // };
  // const oktaAuth = new OktaAuth(oktaConfig);

  beforeEach(() => TestBed.configureTestingModule({
    imports: [
        HttpClientTestingModule
      ],
      **providers: [{provide: OKTA_AUTH, useValue: authServiceSpy,**
        useClass: MockAuthService
      },
        {
          provide: HttpClient,
          useValue: jasmine.createSpyObj('HttpClient', ['get', 'put', 'delete', 'post'])
        }]
  }));

  it('should test getStore', () => {
    httpClientSpy = TestBed.get(HttpClient);
    httpClientSpy.get.and.returnValue(of(dealerJSON));
    const service: CustomerService = TestBed.inject(CustService);
    service.getStore(234563).subscribe(store => {
      expect(store).toBeTruthy();
    });
  });
});

And at this phase it throws error:

Chrome Headless 108.0.5351.0 (Windows 10) CustService should test getDealer FAILED
        NullInjectorError: R3InjectorError(DynamicTestModule)[CustService -> InjectionToken okta.auth -> InjectionToken okta.auth]:
          NullInjectorError: No provider for InjectionToken okta.auth!
        error properties: Object({ ngTempTokenPath: null, ngTokenPath: [ 'CustService', 'InjectionToken okta.auth', 'InjectionToken okta.auth' ] })
            at NullInjector.get (node_modules/@angular/core/fesm2015/core.mjs:6344:27)
            at R3Injector.get (node_modules/@angular/core/fesm2015/core.mjs:6771:33)
            at R3Injector.get (node_modules/@angular/core/fesm2015/core.mjs:6771:33)
            at injectInjectorOnly (node_modules/@angular/core/fesm2015/core.mjs:4761:33)
            at ɵɵinject (node_modules/@angular/core/fesm2015/core.mjs:4765:12)
            at Object.factory (ng:///CustomerService/ɵfac.js:4:76)
            at R3Injector.hydrate (node_modules/@angular/core/fesm2015/core.mjs:6872:35)
            at R3Injector.get (node_modules/@angular/core/fesm2015/core.mjs:6760:33)
            at TestBedImpl.inject (node_modules/@angular/core/fesm2015/testing.mjs:26170:52)
            at Function.get (node_modules/@angular/core/fesm2015/testing.mjs:26040:37)
Chrome Headless 108.0.5351.0 (Windows 10): Executed 108 of 219 (3 FAILED) (0 secs / 10.423 secs)

This error is everywhere, where ever I have used okta auth in service file.

And I have also used:

describe('CustService', () => {
  
  const oktaConfig = {
    issuer: 'issuer',
    clientId: 'clientId',
    redirectUri: 'http://localhost:4200/callback'
  };

  **const oktaAuth = new OktaAuth(oktaConfig);**

  beforeEach(() => TestBed.configureTestingModule({
    providers: [
      {
        **provide: OKTA_CONFIG, useValue: {oktaAuth},**
        useClass: MockAuthService
      }
    ],
    imports: [
      RouterTestingModule,
      HttpClientTestingModule
    ]
  }));

  it('should test canActivate success when cust context in token', () => {
    const service: CustService = TestBed.inject(CustService);
    service.canActivate().then(canActivate => {
      expect(canActivate).toBeTruthy();
    });
  });

});

This above test code is working at component level, but fails at service level with injector error

Strange!!

Gautam