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

Refactor session validation logic in Phase Service / AuthComponent #472

Merged
merged 10 commits into from
Oct 7, 2020
11 changes: 4 additions & 7 deletions src/app/auth/auth.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,12 @@ import { GithubService } from '../core/services/github.service';
import { PhaseService } from '../core/services/phase.service';
import { Title } from '@angular/platform-browser';
import { Profile } from './profiles/profiles.component';
import { flatMap, map } from 'rxjs/operators';
import { flatMap } from 'rxjs/operators';
import { UserService } from '../core/services/user.service';
import { GithubEventService } from '../core/services/githubevent.service';
import { ElectronService } from '../core/services/electron.service';
import { ApplicationService } from '../core/services/application.service';
import { session } from 'electron';
import { throwIfFalse } from '../shared/lib/custom-ops';
import { GithubUser } from '../core/models/github-user.model';

const appSetting = require('../../../package.json');
Expand Down Expand Up @@ -170,11 +170,8 @@ export class AuthComponent implements OnInit, OnDestroy {
this.githubService.storeOrganizationDetails(org, dataRepo);

this.phaseService.storeSessionData().pipe(
map((isValidSession: boolean) => {
if (!isValidSession) {
throw new Error('Invalid Session');
}
})
throwIfFalse(isValidSession => isValidSession,
() => new Error('Invalid Session'))
).subscribe(() => {
this.auth.startOAuthProcess();
}, (error) => {
Expand Down
38 changes: 38 additions & 0 deletions src/app/core/models/session.model.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import { pipe } from 'rxjs';
import { throwIfFalse } from '../../shared/lib/custom-ops';

export interface SessionData {
openPhases: string[];
phaseBugReporting: string;
phaseTeamResponse: string;
phaseTesterResponse: string;
phaseModeration: string;
}

export function assertSessionDataIntegrity() {
return pipe(
throwIfFalse(sessionData => sessionData !== undefined,
() => new Error('Session Data Unavailable')),
throwIfFalse(isSessionDataCorrectlyDefined,
() => new Error('Session Data is Incorrectly Defined')),
throwIfFalse(hasOpenPhases,
() => new Error('There are no accessible phases.')));
}

/**
* Ensures that the input session Data has been correctly defined.
* Returns true if satisfies these properties, false otherwise.
* @param sessionData
*/
function isSessionDataCorrectlyDefined(sessionData: SessionData): boolean {
for (const data of Object.values(sessionData)) {
if (data === undefined || data === '') {
return false;
}
}
return true;
}

function hasOpenPhases(sessionData: SessionData): boolean {
return sessionData.openPhases.length !== 0;
}
40 changes: 3 additions & 37 deletions src/app/core/services/phase.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { GithubService } from './github.service';
import { LabelService } from './label.service';
import { UserService } from './user.service';
import { UserRole } from '../models/user.model';
import { SessionData, assertSessionDataIntegrity } from '../models/session.model';
import { MatDialog } from '@angular/material';
import { SessionFixConfirmationComponent } from './session-fix-confirmation/session-fix-confirmation.component';

Expand All @@ -16,15 +17,6 @@ export enum Phase {
phaseModeration = 'phaseModeration'
}


export interface SessionData {
openPhases: string[];
phaseBugReporting: string;
phaseTeamResponse: string;
phaseTesterResponse: string;
phaseModeration: string;
}

@Injectable({
providedIn: 'root',
})
Expand Down Expand Up @@ -89,8 +81,8 @@ export class PhaseService {
*/
storeSessionData(): Observable<boolean> {
return this.fetchSessionData().pipe(
assertSessionDataIntegrity(),
map((sessionData: SessionData) => {
this.assertSessionDataIntegrity(sessionData);
this.updateSessionParameters(sessionData);
return this.currentPhase !== undefined;
})
Expand All @@ -109,14 +101,6 @@ export class PhaseService {
}
}

assertSessionDataIntegrity(sessionData: SessionData): void {
if (sessionData === undefined) {
throw new Error('Session Data Unavailable.');
} else if (!this.isSessionDataCorrectlyDefined(sessionData)) {
throw new Error('Session Data is Incorrectly Defined');
}
}

/**
* Checks if the necessary repository is available and creates it if the permissions are available.
* @param sessionData
Expand Down Expand Up @@ -145,30 +129,12 @@ export class PhaseService {
});
}

/**
* Ensures that the input session Data has been correctly defined.
* Returns true if satisfies these properties, false otherwise.
* @param sessionData
*/
isSessionDataCorrectlyDefined(sessionData: SessionData): boolean {
for (const data of Object.values(sessionData)) {
if (data === undefined || data === '') {
return false;
}
}
return true;
}

/**
* Stores session data and sets current session's phase.
* @throws Error - If there are no open phases in this session.
* @param sessionData
*/
updateSessionParameters(sessionData: SessionData) {
if (sessionData.openPhases.length === 0) {
throw new Error('There are no accessible phases.');
}

this.sessionData = sessionData;
this.currentPhase = Phase[sessionData.openPhases[0]];
this.repoName = sessionData[sessionData.openPhases[0]];
Expand All @@ -194,8 +160,8 @@ export class PhaseService {
*/
sessionSetup(): Observable<any> {
return this.fetchSessionData().pipe(
assertSessionDataIntegrity(),
flatMap((sessionData: SessionData) => {
this.assertSessionDataIntegrity(sessionData);
this.updateSessionParameters(sessionData);
return this.verifySessionAvailability(sessionData);
}),
Expand Down
9 changes: 9 additions & 0 deletions src/app/shared/lib/custom-ops.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { filter, throwIfEmpty } from 'rxjs/operators';
import { pipe } from 'rxjs';

export function throwIfFalse(predicate, error_func) {
return pipe(
filter(v => predicate(v)),
throwIfEmpty(error_func)
);
}