Testing angular guards

PHOTO EMBED

Sat Jun 24 2023 10:10:33 GMT+0000 (Coordinated Universal Time)

Saved by @mtommasi

// authentication.guard.spec.ts
----------- example 1 -------------------------------------
@Component({ standalone: true, template: "" })
class DashboardComponent {}
describe("AuthenticationGuard", () => {
  let routes: Route[];

  beforeEach(() => {
    routes = [
      {
        path: "dashboard",
        canActivate: [AuthenticationGuard()],
        component: DashboardComponent,
      },
    ];
  });

  it("should initiate the login flow if there is no valid token", async () => {
    const mockOAuthService = {
      hasValidAccessToken: jest.fn().mockReturnValue(false),
      initCodeFlow: jest.fn(),
    };
    const mockAuthRedirectService = { saveRoute: jest.fn() };
    TestBed.configureTestingModule({
      imports: [HttpClientTestingModule],
      providers: [
        { provide: OAuthService, useValue: mockOAuthService },
        { provide: AuthRedirectService, useValue: mockAuthRedirectService },
        provideRouter(routes),
      ],
    });
    await RouterTestingHarness.create("/dashboard");
    expect(mockOAuthService.initCodeFlow).toHaveBeenCalled();
    expect(mockAuthRedirectService.saveRoute).toHaveBeenCalledWith(
      "/dashboard"
    );
  });

  it("should allow access to the dashboard if the token is valid", async () => {
    const mockOAuthService = {
      hasValidAccessToken: jest.fn().mockReturnValue(true),
      initCodeFlow: jest.fn(),
    };
    const mockAuthRedirectService = { saveRoute: jest.fn() };
    TestBed.configureTestingModule({
      imports: [HttpClientTestingModule],
      providers: [
        { provide: OAuthService, useValue: mockOAuthService },
        { provide: AuthRedirectService, useValue: mockAuthRedirectService },
        provideRouter(routes),
      ],
    });
    await RouterTestingHarness.create("/dashboard");
    expect(TestBed.inject(Router).url).toEqual("/dashboard");
  });

  it("should allow access to the dashboard if the token is not valid but there is a code query param", async () => {
    const mockOAuthService = {
      hasValidAccessToken: jest.fn().mockReturnValue(false),
      initCodeFlow: jest.fn(),
    };
    const mockAuthRedirectService = { saveRoute: jest.fn() };
    TestBed.configureTestingModule({
      imports: [HttpClientTestingModule],
      providers: [
        { provide: OAuthService, useValue: mockOAuthService },
        { provide: AuthRedirectService, useValue: mockAuthRedirectService },
        provideRouter(routes),
      ],
    });
    await RouterTestingHarness.create("/dashboard?code=1234");
    expect(TestBed.inject(Router).url).toEqual("/dashboard?code=1234");
  });
});

------------------- EXAMPLE 2 --------------------------

@Component({ standalone: true, template: "" })
class AdminComponent {}
@Component({ standalone: true, template: "" })
class LoginComponent {}

describe("FeatureFlagGuard", () => {
  let routes: Route[];
  let httpMock: HttpTestingController;

  beforeEach(() => {
    routes = [
      {
        path: "test",
        canActivate: [FeatureFlagGuard("test", "/")],
        component: AdminComponent,
      },
      { path: "home", component: LoginComponent },
    ];
  });

  it("should route back to the home route if the flag is not present and it defaults to off", async () => {
    TestBed.configureTestingModule({
      imports: [
        HttpClientTestingModule,
        SharedUtilitiesFeatureFlagsModule.forRoot({
          defaultToFlagOff: true,
          jsonUrl: "/assets/test.config.json",
        }),
      ],
      providers: [provideRouter(routes)],
    });
    httpMock = TestBed.inject(HttpTestingController);
    const mockRequest = httpMock.expectOne("/assets/test.config.json");
    mockRequest.flush({});
    await RouterTestingHarness.create("/test");
    expect(TestBed.inject(Router).url).toEqual("/");
  });

  it("should route to the test route if the flag is not present and it does not default to off", async () => {
    TestBed.configureTestingModule({
      imports: [
        HttpClientTestingModule,
        SharedUtilitiesFeatureFlagsModule.forRoot({
          defaultToFlagOff: false,
          jsonUrl: "/assets/test.config.json",
        }),
      ],
      providers: [provideRouter(routes)],
    });
    httpMock = TestBed.inject(HttpTestingController);
    const mockRequest = httpMock.expectOne("/assets/test.config.json");
    mockRequest.flush({});
    await RouterTestingHarness.create("/test");
    expect(TestBed.inject(Router).url).toEqual("/test");
  });

  it("should route to the test route if the flag is turned on", async () => {
    TestBed.configureTestingModule({
      imports: [
        HttpClientTestingModule,
        SharedUtilitiesFeatureFlagsModule.forRoot({
          defaultToFlagOff: true,
          jsonUrl: "/assets/test.config.json",
        }),
      ],
      providers: [provideRouter(routes)],
    });
    httpMock = TestBed.inject(HttpTestingController);
    const mockRequest = httpMock.expectOne("/assets/test.config.json");
    mockRequest.flush({ test: true });
    await RouterTestingHarness.create("/test");
    expect(TestBed.inject(Router).url).toEqual("/test");
  });

  it("should not route to the test route if the flag is turned off", async () => {
    TestBed.configureTestingModule({
      imports: [
        HttpClientTestingModule,
        SharedUtilitiesFeatureFlagsModule.forRoot({
          defaultToFlagOff: true,
          jsonUrl: "/assets/test.config.json",
        }),
      ],
      providers: [provideRouter(routes)],
    });
    httpMock = TestBed.inject(HttpTestingController);
    const mockRequest = httpMock.expectOne("/assets/test.config.json");
    mockRequest.flush({ test: false });
    await RouterTestingHarness.create("/test");
    expect(TestBed.inject(Router).url).toEqual("/");
  });
});
content_copyCOPY

https://medium.com/ngconf/functional-route-guards-in-angular-8829f0e4ca5c