ipsos-components
Version:
Material Design components for Angular
173 lines (147 loc) • 6.33 kB
text/typescript
import {Injectable} from '@angular/core';
import {HttpClient} from '@angular/common/http';
import * as firebase from 'firebase';
const config = require('../config.json');
import {ScreenshotResultSummary} from './screenshot-result';
/** The service to fetch data from firebase database */
export class FirebaseService {
/** The current user */
user: firebase.User;
/** The screenshot results */
screenshotResultSummary: ScreenshotResultSummary;
constructor(private _httpClient: HttpClient) {
// Initialize Firebase
firebase.initializeApp(config.firebase);
firebase.auth().onAuthStateChanged((user: firebase.User) => {
this.user = user;
});
}
/** Get the firebase storage test image folder url */
getTestScreenshotImageUrl(filename: string): firebase.Promise<string> {
return this._storageRef().child('test').child(filename).getDownloadURL();
}
/** Get the firebase storage diff image folder url */
getDiffScreenshotImageUrl(filename: string): firebase.Promise<string> {
return this._storageRef().child('diff').child(filename).getDownloadURL();
}
/** Get the firebase storage golden image folder url */
getGoldScreenshotImageUrl(filename: string): firebase.Promise<string> {
return firebase.storage().ref('goldens').child(filename).getDownloadURL();
}
/** Set pull request number. All test information and pull request information will be retrived
* from database
*/
set prNumber(prNumber: string) {
this.screenshotResultSummary = new ScreenshotResultSummary();
this.screenshotResultSummary.prNumber = prNumber;
this._readPullRequestScreenshotReport();
}
_readPullRequestScreenshotReport() {
if (!this.screenshotResultSummary.prNumber) {
return;
}
this._databaseRef().on('value', (snapshot: firebase.database.DataSnapshot) => {
let counter = 0;
snapshot.forEach((childSnapshot: firebase.database.DataSnapshot) => {
let childValue = childSnapshot.val();
switch (childSnapshot.key) {
case 'sha':
this._readSha(childValue);
break;
case 'travis':
this.screenshotResultSummary.travis = childValue;
break;
case 'results':
this._readResults(childSnapshot);
break;
}
counter++;
return counter === snapshot.numChildren();
});
});
}
signIntoGithub(): firebase.Promise<void> {
return firebase.auth().signInWithRedirect(new firebase.auth.GithubAuthProvider());
}
signOutFromGithub() {
firebase.auth().signOut();
}
/** Change the PR status to approved to let Firebase Functions copy test images to goldens */
approvePullRequest() {
return this._databaseRef().child('approved').child(this.screenshotResultSummary.sha)
.set(Date.now());
}
/**
* Change the commit's screenshot test status on GitHub
* The value in result/$sha/$result will trigger GitHub status update:
* true - The GitHub status for this SHA will become `success` for Screenshot Test
* false - The GitHub status for this SHA will become `failure` for Screenshot Test
* In this dashboard, we only approve pull requests, so the value is always `true`
*/
updatePullRequestResult() {
return this._databaseRef().child('result').child(this.screenshotResultSummary.sha)
.set(true);
}
/** Reference to the firebase database where the JSON test results and meatadate is stored. */
_databaseRef(): firebase.database.Reference {
return firebase.database().ref('screenshot').child('reports')
.child(this.screenshotResultSummary.prNumber);
}
/** Reference to the firebase storage bucket where the screenshot PNG files are stored. */
_storageRef(): firebase.storage.Reference {
return firebase.storage().ref('screenshots').child(this.screenshotResultSummary.prNumber);
}
/** Read the results from database adn put the results in screenshotReusltSummary */
_readResults(childSnapshot: firebase.database.DataSnapshot) {
let childCounter = 0;
this.screenshotResultSummary.collapse = [];
this.screenshotResultSummary.testNames = [];
this.screenshotResultSummary.testResultsByName.clear();
childSnapshot.forEach((resultSnapshot: firebase.database.DataSnapshot) => {
if (resultSnapshot.key) {
this._addTestResults(resultSnapshot.key, resultSnapshot.val());
}
childCounter++;
return childCounter === childSnapshot.numChildren();
});
}
_addTestResults(name: string, value: boolean) {
this.screenshotResultSummary.testResultsByName.set(name, value);
this.screenshotResultSummary.testNames.push(name);
this.screenshotResultSummary.collapse.push(value);
}
/** Read SHA and approved status from database and put them in ScreenshotResultSummary */
_readSha(childValue) {
this.screenshotResultSummary.sha = childValue;
// Get github status
this.getGithubStatus();
// Get test allTestsPassedOrApproved
this._databaseRef().child(`result/${childValue}`).once('value')
.then((dataSnapshot: firebase.database.DataSnapshot) => {
this.screenshotResultSummary.allTestsPassedOrApproved = dataSnapshot.val();
});
// Get the approved SHA and date time
this._databaseRef().child(`approved/${childValue}`).once('value')
.then((dataSnapshot: firebase.database.DataSnapshot) => {
this.screenshotResultSummary.approvedTime = dataSnapshot.val();
});
}
getGithubStatus() {
let url =
`https://api.github.com/repos/${config.repoSlug}/commits/` +
`${this.screenshotResultSummary.sha}/status`;
return this._httpClient.get<{statuses: any[]}>(url).toPromise().then(response => {
const screenshotStatus = response.statuses.find(status =>
status.context === 'Screenshot Tests');
switch (screenshotStatus && screenshotStatus.state) {
case 'success':
this.screenshotResultSummary.githubStatus = true;
break;
case 'failure':
this.screenshotResultSummary.githubStatus = false;
return;
}
});
}
}