Skip to content

Commit

Permalink
Routing tests.
Browse files Browse the repository at this point in the history
Github redirect encapsulated in a service to allow mocking
  • Loading branch information
zaychenko-sergei committed Aug 23, 2023
1 parent 4456068 commit 731535b
Show file tree
Hide file tree
Showing 7 changed files with 120 additions and 16 deletions.
8 changes: 3 additions & 5 deletions src/app/app-routing.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,13 @@ import { DatasetComponent } from "./dataset-view/dataset.component";
import { DatasetCreateComponent } from "./dataset-create/dataset-create.component";
import { AccountComponent } from "./auth/account/account.component";
import { GithubCallbackComponent } from "./auth/github-callback/github.callback";
import { environment } from "../environments/environment";
import ProjectLinks from "./project-links";
import { SetTransformComponent } from "./dataset-view/additional-components/metadata-component/components/set-transform/set-transform.component";
import { LoginGuard } from "./auth/guards/login.guard";

const githubUrl = `https://github.com/login/oauth/authorize?scope=user:email&client_id=${environment.github_client_id}`;
import { LoginService } from "./auth/login/login.service";

export const routes: Routes = [
{ path: "", redirectTo: ProjectLinks.URL_SEARCH, pathMatch: "full" },
{ path: "", redirectTo: ProjectLinks.DEFAULT_URL, pathMatch: "full" },
{
path: ProjectLinks.URL_GITHUB_CALLBACK,
component: GithubCallbackComponent,
Expand All @@ -30,7 +28,7 @@ export const routes: Routes = [
canLoad: [LoginGuard],
loadChildren: () =>
new Promise(() => {
window.location.href = githubUrl;
LoginService.gotoGithub();
}),
},
{
Expand Down
104 changes: 96 additions & 8 deletions src/app/app-routing.spec.ts
Original file line number Diff line number Diff line change
@@ -1,37 +1,125 @@
import { ComponentFixture, TestBed, fakeAsync, tick } from "@angular/core/testing";
import { ComponentFixture, TestBed, fakeAsync, flush, tick } from "@angular/core/testing";
import { Location } from "@angular/common";
import { Router } from "@angular/router";
import { RouterTestingModule } from "@angular/router/testing";
import { routes } from "./app-routing.module";
import { AppComponent } from "./app.component";
import ProjectLinks from "./project-links";
import { promiseWithCatch } from "./common/app.helpers";
import { ApolloTestingModule } from "apollo-angular/testing";
import { NO_ERRORS_SCHEMA } from "@angular/core";
import { LoggedUserService } from "./auth/logged-user.service";
import { AppConfigService } from "./app-config.service";
import { LoginService } from "./auth/login/login.service";
import { PageNotFoundComponent } from "./components/page-not-found/page-not-found.component";

describe("Router: App", () => {
describe("Router", () => {
let router: Router;
let fixture: ComponentFixture<AppComponent>;
let fixture: ComponentFixture<PageNotFoundComponent>; // any component is fine, we are testing router
let location: Location;
let loggedUserService: LoggedUserService;
let appConfigService: AppConfigService;

beforeEach(async () => {
await TestBed.configureTestingModule({
imports: [RouterTestingModule.withRoutes(routes), ApolloTestingModule],
declarations: [AppComponent],
declarations: [PageNotFoundComponent],
schemas: [NO_ERRORS_SCHEMA],
}).compileComponents();

router = TestBed.inject(Router);
location = TestBed.inject(Location);
loggedUserService = TestBed.inject(LoggedUserService);
appConfigService = TestBed.inject(AppConfigService);

fixture = TestBed.createComponent(AppComponent);
fixture = TestBed.createComponent(PageNotFoundComponent);
router.initialNavigation();
fixture.detectChanges();
});

it('navigate to "" redirects you to search', fakeAsync(() => {
it("navigate to home redirects you to default URL", fakeAsync(() => {
promiseWithCatch(router.navigate([""]));
tick();
expect(location.path()).toBe("/" + ProjectLinks.URL_SEARCH);

expect(location.path()).toBe("/" + ProjectLinks.DEFAULT_URL);
flush();
}));

[
ProjectLinks.URL_GITHUB_CALLBACK,
ProjectLinks.URL_SEARCH,
`myaccount`,
`myaccount/mydataset`,
`myaccount/mydataset/${ProjectLinks.URL_BLOCK}/:someHash`,
ProjectLinks.URL_PAGE_NOT_FOUND,
"dummy",
].forEach((url: string) => {
it(`Route to ${url} lands on the component without Login`, fakeAsync(() => {
promiseWithCatch(router.navigate([url]));
tick();

expect(location.path()).toBe("/" + url);
flush();
}));
});

[
ProjectLinks.URL_DATASET_CREATE,
ProjectLinks.URL_SETTINGS,
`myaccount/mydataset/${ProjectLinks.URL_PARAM_ADD_POLLING_SOURCE}`,
`myaccount/mydataset/${ProjectLinks.URL_PARAM_SET_TRANSFORM}`,
].forEach((url: string) => {
it(`Route to ${url} fails without a login and moves to Home`, fakeAsync(() => {
promiseWithCatch(router.navigate([url]));
tick();

expect(location.path()).toBe("/" + ProjectLinks.DEFAULT_URL);
flush();
}));

it(`Route to ${url} lands on the component with active login`, fakeAsync(() => {
spyOnProperty(loggedUserService, "isAuthenticated", "get").and.returnValue(true);

promiseWithCatch(router.navigate([url]));
tick();

expect(location.path()).toBe("/" + url);
flush();
}));
});

describe("#login routes", () => {
it("login redirects to default page when not allowed in configuration", fakeAsync(() => {
spyOnProperty(appConfigService, "featureFlags", "get").and.returnValue({
enableLogin: false,
enableLogout: true,
});

promiseWithCatch(router.navigate([ProjectLinks.URL_LOGIN]));
tick();

expect(location.path()).toBe("/" + ProjectLinks.URL_SEARCH);
flush();
}));

it("login redirects to default page when user is already logged", fakeAsync(() => {
spyOnProperty(loggedUserService, "isAuthenticated", "get").and.returnValue(true);

promiseWithCatch(router.navigate([ProjectLinks.URL_LOGIN]));
tick();

expect(location.path()).toBe("/" + ProjectLinks.URL_SEARCH);
flush();
}));

it("login initiates GitHub redirect when allowed and not logged in", fakeAsync(() => {
spyOnProperty(loggedUserService, "isAuthenticated", "get").and.returnValue(false);
const gotoGithubSpy = spyOn(LoginService, "gotoGithub");

promiseWithCatch(router.navigate([ProjectLinks.URL_LOGIN]));
tick();

expect(gotoGithubSpy).toHaveBeenCalledWith();
flush();
}));
});
});
2 changes: 2 additions & 0 deletions src/app/app.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ import { HighlightModule, HIGHLIGHT_OPTIONS } from "ngx-highlightjs";
import { ToastrModule } from "ngx-toastr";
import { LoggedUserService } from "./auth/logged-user.service";
import { firstValueFrom } from "rxjs";
import { LoginService } from "./auth/login/login.service";

const Services = [
{
Expand All @@ -78,6 +79,7 @@ const Services = [
},
Apollo,
AuthApi,
LoginService,
LoggedUserService,
SearchApi,
DatasetApi,
Expand Down
2 changes: 1 addition & 1 deletion src/app/auth/login/login.component.html
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
<p>Please login with your <strong>GitHub account</strong>.</p>
<a href="{{ githubUrl }}" class="login__btn login__btn--full" md-raised-button="primary"> Login </a>
<a href="{{ GITHUB_URL }}" class="login__btn login__btn--full" md-raised-button="primary"> Login </a>
4 changes: 2 additions & 2 deletions src/app/auth/login/login.component.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { ChangeDetectionStrategy, Component } from "@angular/core";
import { environment } from "../../../environments/environment";
import ProjectLinks from "src/app/project-links";

@Component({
selector: "app-login",
Expand All @@ -8,5 +8,5 @@ import { environment } from "../../../environments/environment";
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class LoginComponent {
public githubUrl = `https://github.com/login/oauth/authorize?scope=user:email&client_id=${environment.github_client_id}`;
public readonly GITHUB_URL = ProjectLinks.GITHUB_URL;
}
11 changes: 11 additions & 0 deletions src/app/auth/login/login.service.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { Injectable } from "@angular/core";
import ProjectLinks from "src/app/project-links";

@Injectable({
providedIn: "root",
})
export class LoginService {
public static gotoGithub(): void {
window.location.href = ProjectLinks.GITHUB_URL;
}
}
5 changes: 5 additions & 0 deletions src/app/project-links.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { Injectable } from "@angular/core";
import { environment } from "src/environments/environment";

@Injectable()
export default class ProjectLinks {
Expand All @@ -22,6 +23,8 @@ export default class ProjectLinks {
ProjectLinks.URL_SETTINGS,
];

public static readonly DEFAULT_URL = ProjectLinks.URL_SEARCH;

public static readonly URL_PARAM_ACCOUNT_NAME: string = "accountName";
public static readonly URL_PARAM_DATASET_NAME: string = "datasetName";
public static readonly URL_PARAM_CATEGORY: string = "category";
Expand All @@ -33,6 +36,8 @@ export default class ProjectLinks {
public static readonly URL_QUERY_PARAM_PAGE: string = "page";
public static readonly URL_QUERY_PARAM_QUERY: string = "query";

public static readonly GITHUB_URL = `https://github.com/login/oauth/authorize?scope=user:email&client_id=${environment.github_client_id}`;

// TODO
// public static readonly URL_DATASET_CREATE_SELECT_TYPE = "select-type";
// public static readonly URL_DATASET_CREATE_ROOT = "root";
Expand Down

0 comments on commit 731535b

Please sign in to comment.