Transfering from old repo
17
.browserslistrc
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
# This file is used by the build system to adjust CSS and JS output to support the specified browsers below.
|
||||
# For additional information regarding the format and rule options, please see:
|
||||
# https://github.com/browserslist/browserslist#queries
|
||||
|
||||
# For the full list of supported browsers by the Angular framework, please see:
|
||||
# https://angular.io/guide/browser-support
|
||||
|
||||
# You can see what browsers were selected by your queries by running:
|
||||
# npx browserslist
|
||||
|
||||
last 1 Chrome version
|
||||
last 1 Firefox version
|
||||
last 2 Edge major versions
|
||||
last 2 Safari major versions
|
||||
last 2 iOS major versions
|
||||
Firefox ESR
|
||||
not IE 11 # Angular supports IE 11 only as an opt-in. To opt-in, remove the 'not' prefix on this line.
|
||||
16
.editorconfig
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
# Editor configuration, see https://editorconfig.org
|
||||
root = true
|
||||
|
||||
[*]
|
||||
charset = utf-8
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
insert_final_newline = true
|
||||
trim_trailing_whitespace = true
|
||||
|
||||
[*.ts]
|
||||
quote_type = single
|
||||
|
||||
[*.md]
|
||||
max_line_length = off
|
||||
trim_trailing_whitespace = false
|
||||
45
.gitignore
vendored
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
# See http://help.github.com/ignore-files/ for more about ignoring files.
|
||||
|
||||
# compiled output
|
||||
/dist
|
||||
/tmp
|
||||
/out-tsc
|
||||
# Only exists if Bazel was run
|
||||
/bazel-out
|
||||
|
||||
# dependencies
|
||||
/node_modules
|
||||
|
||||
# profiling files
|
||||
chrome-profiler-events*.json
|
||||
|
||||
# IDEs and editors
|
||||
/.idea
|
||||
.project
|
||||
.classpath
|
||||
.c9/
|
||||
*.launch
|
||||
.settings/
|
||||
*.sublime-workspace
|
||||
|
||||
# IDE - VSCode
|
||||
.vscode/*
|
||||
!.vscode/settings.json
|
||||
!.vscode/tasks.json
|
||||
!.vscode/launch.json
|
||||
!.vscode/extensions.json
|
||||
.history/*
|
||||
|
||||
# misc
|
||||
/.sass-cache
|
||||
/connect.lock
|
||||
/coverage
|
||||
/libpeerconnection.log
|
||||
npm-debug.log
|
||||
yarn-error.log
|
||||
testem.log
|
||||
/typings
|
||||
|
||||
# System Files
|
||||
.DS_Store
|
||||
Thumbs.db
|
||||
1
Diagram.drawio
Normal file
|
|
@ -0,0 +1 @@
|
|||
<mxfile host="app.diagrams.net" modified="2021-10-27T20:25:46.655Z" agent="5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.0 Safari/605.1.15" etag="2AcS9_i4EcT-0jyiaAU8" version="15.6.0" type="device"><diagram id="zMaeALjWRC1t_pE46dh5" name="Page-1">7VhNc5swEP01PjYDyHbtY/3RJDNNpzM+tDllZNggNYJ1hbBNf31XWBgIiSfpJGMOOaF92tXHeyvtiAGbJ/tLzTfiBiNQg8CL9gO2GASBH7AhfSxSHJCJPzkAsZaRc6qBlfwLDvQcmssIspajQVRGbtpgiGkKoWlhXGvctd3uUbVn3fAYOsAq5KqL/pSREW4XI6/Gr0DGoprZ91xPwitnB2SCR7hrQGw5YHONaA6tZD8HZcmreDnEfX2m97gwDal5ScDd3SyOM5g9/FlNZ3mWX+Ek/FSpkZmi2jFERIAzURuBMaZcLWt0pjFPI7DDemTVPt8QNwT6BP4GYwqnJs8NEiRMolwv7KX5ZcMvRs66dYPZ9mLfNIrKSI0uGkHWvK3Gs0YdVlpV3GF/dlPP8uagDHMdwimyRi4BuY7BnHIcH/WlgwGYAK2IAjUobuS2vRLuMjQ++tUiUsPp+ApNbXxfNPX/S1Ovj5pOz6rp6EPTt9e0cQ+fQdNqmVuucjfVFQ1dVqTHYu+ENLDa8HLfOyq1baG4knFK7ZC4An1kcwvawP40n93duwDG3Ppc5fanrpDt6jroTxwmGjVw7L0XYeMOYd/5ds11L+gat+l6iq3gCbaG78VWMPy4Ml5+ZUxfemWws14Z084J+KF4Ab04AcFnr3UCWHD2I+B1b1jQ2AeyhuPekcU6ZN1wEwp6ffWAr8fJNfTPzle3Gl3SBZASlGf2RHqC5rS8AU+uqXte92QCc3qIBt4a7NLWCsp3re0BrkNRvlStoxHc0Od6cTGwmxvzxHKdrjP7WZEKzcGosatjNu5isNNyhWlckmVE6QFSH96o5VxCZgZ1cdERmvQybW0zo/EB5qhoeWyRYmqrxr1U6hHUyQGrvqR39RfXkcgoKkvOU8nULkNvUZ3b2TNi3ew5+jSz5/icf0X6kFm/6su+xr8RtvwH</diagram></mxfile>
|
||||
27
README.md
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
# EZDotaUI
|
||||
|
||||
This project was generated with [Angular CLI](https://github.com/angular/angular-cli) version 12.1.1.
|
||||
|
||||
## Development server
|
||||
|
||||
Run `ng serve` for a dev server. Navigate to `http://localhost:4200/`. The app will automatically reload if you change any of the source files.
|
||||
|
||||
## Code scaffolding
|
||||
|
||||
Run `ng generate component component-name` to generate a new component. You can also use `ng generate directive|pipe|service|class|guard|interface|enum|module`.
|
||||
|
||||
## Build
|
||||
|
||||
Run `ng build` to build the project. The build artifacts will be stored in the `dist/` directory.
|
||||
|
||||
## Running unit tests
|
||||
|
||||
Run `ng test` to execute the unit tests via [Karma](https://karma-runner.github.io).
|
||||
|
||||
## Running end-to-end tests
|
||||
|
||||
Run `ng e2e` to execute the end-to-end tests via a platform of your choice. To use this command, you need to first add a package that implements end-to-end testing capabilities.
|
||||
|
||||
## Further help
|
||||
|
||||
To get more help on the Angular CLI use `ng help` or go check out the [Angular CLI Overview and Command Reference](https://angular.io/cli) page.
|
||||
115
angular.json
Normal file
|
|
@ -0,0 +1,115 @@
|
|||
{
|
||||
"$schema": "./node_modules/@angular/cli/lib/config/schema.json",
|
||||
"version": 1,
|
||||
"newProjectRoot": "projects",
|
||||
"projects": {
|
||||
"EZDota-UI": {
|
||||
"projectType": "application",
|
||||
"schematics": {
|
||||
"@schematics/angular:component": {
|
||||
"style": "scss"
|
||||
},
|
||||
"@schematics/angular:application": {
|
||||
"strict": true
|
||||
}
|
||||
},
|
||||
"root": "",
|
||||
"sourceRoot": "src",
|
||||
"prefix": "app",
|
||||
"architect": {
|
||||
"build": {
|
||||
"builder": "@angular-devkit/build-angular:browser",
|
||||
"options": {
|
||||
"outputPath": "dist/EZDota-UI",
|
||||
"index": "src/index.html",
|
||||
"main": "src/main.ts",
|
||||
"polyfills": "src/polyfills.ts",
|
||||
"tsConfig": "tsconfig.app.json",
|
||||
"inlineStyleLanguage": "scss",
|
||||
"assets": [
|
||||
"src/favicon.ico",
|
||||
"src/assets"
|
||||
],
|
||||
"styles": [
|
||||
"src/styles.scss",
|
||||
"node_modules/bootstrap/dist/css/bootstrap.min.css"
|
||||
],
|
||||
"scripts": [
|
||||
"node_modules/jquery/dist/jquery.min.js",
|
||||
"node_modules/bootstrap/dist/js/bootstrap.min.js"
|
||||
]
|
||||
},
|
||||
"configurations": {
|
||||
"production": {
|
||||
"budgets": [
|
||||
{
|
||||
"type": "initial",
|
||||
"maximumWarning": "500kb",
|
||||
"maximumError": "1mb"
|
||||
},
|
||||
{
|
||||
"type": "anyComponentStyle",
|
||||
"maximumWarning": "2kb",
|
||||
"maximumError": "4kb"
|
||||
}
|
||||
],
|
||||
"fileReplacements": [
|
||||
{
|
||||
"replace": "src/environments/environment.ts",
|
||||
"with": "src/environments/environment.prod.ts"
|
||||
}
|
||||
],
|
||||
"outputHashing": "all"
|
||||
},
|
||||
"development": {
|
||||
"buildOptimizer": false,
|
||||
"optimization": false,
|
||||
"vendorChunk": true,
|
||||
"extractLicenses": false,
|
||||
"sourceMap": true,
|
||||
"namedChunks": true
|
||||
}
|
||||
},
|
||||
"defaultConfiguration": "production"
|
||||
},
|
||||
"serve": {
|
||||
"builder": "@angular-devkit/build-angular:dev-server",
|
||||
"configurations": {
|
||||
"production": {
|
||||
"browserTarget": "EZDota-UI:build:production"
|
||||
},
|
||||
"development": {
|
||||
"browserTarget": "EZDota-UI:build:development"
|
||||
}
|
||||
},
|
||||
"defaultConfiguration": "development"
|
||||
},
|
||||
"extract-i18n": {
|
||||
"builder": "@angular-devkit/build-angular:extract-i18n",
|
||||
"options": {
|
||||
"browserTarget": "EZDota-UI:build"
|
||||
}
|
||||
},
|
||||
"test": {
|
||||
"builder": "@angular-devkit/build-angular:karma",
|
||||
"options": {
|
||||
"main": "src/test.ts",
|
||||
"polyfills": "src/polyfills.ts",
|
||||
"tsConfig": "tsconfig.spec.json",
|
||||
"karmaConfig": "karma.conf.js",
|
||||
"inlineStyleLanguage": "scss",
|
||||
"assets": [
|
||||
"src/favicon.ico",
|
||||
"src/assets"
|
||||
],
|
||||
"styles": [
|
||||
"src/styles.scss"
|
||||
],
|
||||
"scripts": []
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"defaultProject": "EZDota-UI"
|
||||
}
|
||||
44
karma.conf.js
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
// Karma configuration file, see link for more information
|
||||
// https://karma-runner.github.io/1.0/config/configuration-file.html
|
||||
|
||||
module.exports = function (config) {
|
||||
config.set({
|
||||
basePath: '',
|
||||
frameworks: ['jasmine', '@angular-devkit/build-angular'],
|
||||
plugins: [
|
||||
require('karma-jasmine'),
|
||||
require('karma-chrome-launcher'),
|
||||
require('karma-jasmine-html-reporter'),
|
||||
require('karma-coverage'),
|
||||
require('@angular-devkit/build-angular/plugins/karma')
|
||||
],
|
||||
client: {
|
||||
jasmine: {
|
||||
// you can add configuration options for Jasmine here
|
||||
// the possible options are listed at https://jasmine.github.io/api/edge/Configuration.html
|
||||
// for example, you can disable the random execution with `random: false`
|
||||
// or set a specific seed with `seed: 4321`
|
||||
},
|
||||
clearContext: false // leave Jasmine Spec Runner output visible in browser
|
||||
},
|
||||
jasmineHtmlReporter: {
|
||||
suppressAll: true // removes the duplicated traces
|
||||
},
|
||||
coverageReporter: {
|
||||
dir: require('path').join(__dirname, './coverage/EZDota-UI'),
|
||||
subdir: '.',
|
||||
reporters: [
|
||||
{ type: 'html' },
|
||||
{ type: 'text-summary' }
|
||||
]
|
||||
},
|
||||
reporters: ['progress', 'kjhtml'],
|
||||
port: 9876,
|
||||
colors: true,
|
||||
logLevel: config.LOG_INFO,
|
||||
autoWatch: true,
|
||||
browsers: ['Chrome'],
|
||||
singleRun: false,
|
||||
restartOnFileChange: true
|
||||
});
|
||||
};
|
||||
12914
package-lock.json
generated
Normal file
49
package.json
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
{
|
||||
"name": "ezdota-ui",
|
||||
"version": "0.0.0",
|
||||
"scripts": {
|
||||
"ng": "ng",
|
||||
"start": "ng serve",
|
||||
"build": "ng build",
|
||||
"watch": "ng build --watch --configuration development",
|
||||
"test": "ng test"
|
||||
},
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"@angular/animations": "~12.2.12",
|
||||
"@angular/common": "~12.2.12",
|
||||
"@angular/compiler": "~12.2.12",
|
||||
"@angular/core": "~12.2.12",
|
||||
"@angular/forms": "~12.2.12",
|
||||
"@angular/platform-browser": "~12.2.12",
|
||||
"@angular/platform-browser-dynamic": "~12.2.12",
|
||||
"@angular/router": "~12.2.12",
|
||||
"@auth0/auth0-angular": "^1.8.0",
|
||||
"@ng-bootstrap/ng-bootstrap": "^10.0.0",
|
||||
"@types/jquery": "^3.5.8",
|
||||
"angular-bootstrap-toasts": "^1.2.0",
|
||||
"auth0": "^2.37.0",
|
||||
"bignumber": "^1.1.0",
|
||||
"bootstrap": "^4.6.1",
|
||||
"jquery": "^3.6.0",
|
||||
"ngb-toast": "0.0.6",
|
||||
"rxjs": "~6.6.0",
|
||||
"tslib": "^2.2.0",
|
||||
"util": "^0.12.4",
|
||||
"zone.js": "~0.11.4"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@angular-devkit/build-angular": "~12.1.1",
|
||||
"@angular/cli": "~12.1.1",
|
||||
"@angular/compiler-cli": "~12.2.12",
|
||||
"@types/jasmine": "~3.6.0",
|
||||
"@types/node": "^12.20.37",
|
||||
"jasmine-core": "~3.7.0",
|
||||
"karma": "~6.3.0",
|
||||
"karma-chrome-launcher": "~3.1.0",
|
||||
"karma-coverage": "~2.0.3",
|
||||
"karma-jasmine": "~4.0.0",
|
||||
"karma-jasmine-html-reporter": "^1.5.0",
|
||||
"typescript": "~4.3.2"
|
||||
}
|
||||
}
|
||||
15
src/app/app-routing.module.ts
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
import { NgModule } from '@angular/core';
|
||||
import { RouterModule, Routes } from '@angular/router';
|
||||
import { HomepageComponent } from './components/homepage/homepage.component';
|
||||
import { SavedPlayerComponent } from './components/saved-player/saved-player.component';
|
||||
import { SplayerComponent } from './components/splayer/splayer.component';
|
||||
import { UserProfileComponent } from './components/user-profile/user-profile.component';
|
||||
|
||||
const routes: Routes = [{path:'', component: HomepageComponent},{path:'player', component: SplayerComponent},{path:'profile', component: UserProfileComponent},{path:'saved-player',component: SavedPlayerComponent}];
|
||||
|
||||
@NgModule({
|
||||
declarations: [],
|
||||
imports: [RouterModule.forRoot(routes)],
|
||||
exports: [RouterModule]
|
||||
})
|
||||
export class AppRoutingModule { }
|
||||
5
src/app/app.component.html
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
<div class="p-3 mb-2 bg-dark text-white">
|
||||
<app-navbar></app-navbar>
|
||||
<ngb-toast-container></ngb-toast-container>
|
||||
<router-outlet></router-outlet>
|
||||
</div>
|
||||
0
src/app/app.component.scss
Normal file
25
src/app/app.component.spec.ts
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
import { TestBed } from '@angular/core/testing';
|
||||
import { AppComponent } from './app.component';
|
||||
|
||||
describe('AppComponent', () => {
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
declarations: [
|
||||
AppComponent
|
||||
],
|
||||
}).compileComponents();
|
||||
});
|
||||
|
||||
it('should create the app', () => {
|
||||
const fixture = TestBed.createComponent(AppComponent);
|
||||
const app = fixture.componentInstance;
|
||||
expect(app).toBeTruthy();
|
||||
});
|
||||
|
||||
it(`should have as title 'Dota2Protractor'`, () => {
|
||||
const fixture = TestBed.createComponent(AppComponent);
|
||||
const app = fixture.componentInstance;
|
||||
expect(app.title).toEqual('Dota2Protractor');
|
||||
});
|
||||
|
||||
});
|
||||
14
src/app/app.component.ts
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
import { Component } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'app-root',
|
||||
templateUrl: './app.component.html',
|
||||
styleUrls: ['./app.component.scss']
|
||||
})
|
||||
export class AppComponent {
|
||||
title = 'Dota2Protractor';
|
||||
|
||||
constructor() { }
|
||||
|
||||
}
|
||||
|
||||
43
src/app/app.module.ts
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
import { NgModule } from '@angular/core';
|
||||
import { NgbModule } from '@ng-bootstrap/ng-bootstrap';
|
||||
import { BrowserModule } from '@angular/platform-browser';
|
||||
|
||||
import { AppComponent } from './app.component';
|
||||
import { AppRoutingModule } from './app-routing.module';
|
||||
import { HttpClientModule} from '@angular/common/http';
|
||||
import { HomepageComponent } from './components/homepage/homepage.component';
|
||||
import { NavbarComponent } from './components/navbar/navbar.component';
|
||||
import { SplayerComponent } from './components/splayer/splayer.component';
|
||||
import { AuthModule } from '@auth0/auth0-angular';
|
||||
import { AuthButtonComponent } from './components/auth-button/auth-button.component';
|
||||
import { UserProfileComponent } from './components/user-profile/user-profile.component';
|
||||
import { FormsModule } from '@angular/forms';
|
||||
import { SavedPlayerComponent } from './components/saved-player/saved-player.component';
|
||||
import { NgbToastModule } from 'ngb-toast';
|
||||
|
||||
@NgModule({
|
||||
declarations: [
|
||||
AppComponent,
|
||||
HomepageComponent,
|
||||
NavbarComponent,
|
||||
SplayerComponent,
|
||||
AuthButtonComponent,
|
||||
UserProfileComponent,
|
||||
SavedPlayerComponent
|
||||
],
|
||||
imports: [
|
||||
BrowserModule,
|
||||
HttpClientModule,
|
||||
AppRoutingModule,
|
||||
NgbModule,
|
||||
FormsModule,
|
||||
NgbToastModule,
|
||||
AuthModule.forRoot({
|
||||
domain: 'dev-ulpdvjy2.us.auth0.com',
|
||||
clientId: 'k6E8BCBB1pmYMyAFxpuCw6j025SS3Mdq'
|
||||
}),
|
||||
],
|
||||
providers: [ HttpClientModule ],
|
||||
bootstrap: [AppComponent]
|
||||
})
|
||||
export class AppModule { }
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
<ng-container *ngIf="auth.isAuthenticated$ | async; else loggedOut">
|
||||
<button type="button" class="btn btn-outline-light" (click)="auth.logout({ returnTo: document.location.origin })">
|
||||
Log out
|
||||
</button>
|
||||
</ng-container>
|
||||
|
||||
<ng-template #loggedOut>
|
||||
<button type="button" class="btn btn-outline-light" (click)="auth.loginWithRedirect()">Log in</button>
|
||||
</ng-template>
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
.linkFix{
|
||||
text-decoration: none;
|
||||
color: white;
|
||||
margin-right: 1rem;
|
||||
}
|
||||
28
src/app/components/auth-button/auth-button.component.spec.ts
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
import { AuthModule } from '@auth0/auth0-angular';
|
||||
|
||||
import { AuthButtonComponent } from './auth-button.component';
|
||||
|
||||
describe('AuthButtonComponent', () => {
|
||||
let component: AuthButtonComponent;
|
||||
let fixture: ComponentFixture<AuthButtonComponent>;
|
||||
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
declarations: [ AuthButtonComponent ],
|
||||
imports: [ AuthModule.forRoot({domain: 'dev-ulpdvjy2.us.auth0.com',
|
||||
clientId: 'k6E8BCBB1pmYMyAFxpuCw6j025SS3Mdq'}) ]
|
||||
})
|
||||
.compileComponents();
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(AuthButtonComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
14
src/app/components/auth-button/auth-button.component.ts
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
import { Component, Inject } from '@angular/core';
|
||||
import { AuthService } from '@auth0/auth0-angular';
|
||||
import { DOCUMENT } from '@angular/common';
|
||||
|
||||
@Component({
|
||||
selector: 'app-auth-button',
|
||||
templateUrl: './auth-button.component.html',
|
||||
styleUrls: ['./auth-button.component.scss']
|
||||
})
|
||||
export class AuthButtonComponent {
|
||||
constructor(@Inject(DOCUMENT) public document: Document, public auth: AuthService) {
|
||||
}
|
||||
|
||||
}
|
||||
10
src/app/components/homepage/homepage.component.html
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
<div class="p-3 mb-2 bg-dark text-white">
|
||||
<app-splayer></app-splayer>
|
||||
<!--66914827-->
|
||||
<!-- <div class="player1">
|
||||
<app-player-matches [matches]="matches" [steamid]="'268590680'"></app-player-matches>
|
||||
</div>
|
||||
<div class="player1">
|
||||
<app-hero [heroId]="135"></app-hero>
|
||||
</div> -->
|
||||
</div>
|
||||
0
src/app/components/homepage/homepage.component.scss
Normal file
63
src/app/components/homepage/homepage.component.spec.ts
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
import { of } from 'rxjs';
|
||||
import { AppModule } from 'src/app/app.module';
|
||||
import { Match } from 'src/app/models/match/match.model';
|
||||
import { SPlayer } from 'src/app/models/s-player/splayer.model';
|
||||
import { StratzService } from 'src/app/services/stratz.service';
|
||||
|
||||
import { HomepageComponent } from './homepage.component';
|
||||
|
||||
describe('HomepageComponent', () => {
|
||||
let component: HomepageComponent;
|
||||
let fixture: ComponentFixture<HomepageComponent>;
|
||||
|
||||
let match = new Match();
|
||||
match.id = 1;
|
||||
match.durationSeconds = "1";
|
||||
match.victory = true;
|
||||
match.firstBloodTime = "1";
|
||||
match.gameMode = "1";
|
||||
match.largestGoldLead = "1";
|
||||
match.largestGoldLeadTeam = "Dire";
|
||||
match.largestXpLead = "1";
|
||||
match.largestXpLeadTeam = "Radiant";
|
||||
match.startTime = "1";
|
||||
match.deaths = "1";
|
||||
|
||||
let player = new SPlayer();
|
||||
player.name = "Ryon";
|
||||
player.id = 1;
|
||||
player.realName = "Real Ryon";
|
||||
player.avatar = "link";
|
||||
player.profileUri = "uri";
|
||||
player.matchesList = [];
|
||||
player.matchesList.push(match);
|
||||
|
||||
const stratzServiceSpy = jasmine.createSpyObj('StratzService',[
|
||||
'getPlayer'
|
||||
]);
|
||||
stratzServiceSpy.getPlayer.and.returnValue(of(player));
|
||||
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
declarations: [ HomepageComponent ],
|
||||
imports: [ AppModule ],
|
||||
providers: [
|
||||
{
|
||||
provide: StratzService, useValue: stratzServiceSpy
|
||||
}
|
||||
]
|
||||
})
|
||||
.compileComponents();
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(HomepageComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
16
src/app/components/homepage/homepage.component.ts
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
import { Component, Input, OnInit, ɵCodegenComponentFactoryResolver } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'app-homepage',
|
||||
templateUrl: './homepage.component.html',
|
||||
styleUrls: ['./homepage.component.scss']
|
||||
})
|
||||
export class HomepageComponent implements OnInit {
|
||||
|
||||
|
||||
constructor() { }
|
||||
|
||||
ngOnInit(): void {
|
||||
|
||||
}
|
||||
}
|
||||
25
src/app/components/navbar/navbar.component.html
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
<nav class="navbar navbar-expand-lg navbar-dark bg-dark">
|
||||
<a id="home" class="navbar-brand" routerLink="">Protractor</a>
|
||||
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent"
|
||||
aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
|
||||
<span class="navbar-toggler-icon"></span>
|
||||
</button>
|
||||
|
||||
<div class="collapse navbar-collapse" id="navbarSupportedContent">
|
||||
<ul class="navbar-nav">
|
||||
<li class="nav-item">
|
||||
<a id="saved-match" *ngIf="auth.isAuthenticated$ | async;" class="nav-link" routerLink="/saved-player">Saved
|
||||
Matches</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a id="profile" *ngIf="auth.isAuthenticated$ | async;" class="nav-link" routerLink="/profile">Profile</a>
|
||||
</li>
|
||||
</ul>
|
||||
<ul class="navbar-nav ml-auto">
|
||||
<li class="nav-item">
|
||||
<img *ngIf="auth.user$ | async as user" src="{{user.picture}}">
|
||||
<app-auth-button></app-auth-button>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</nav>
|
||||
22
src/app/components/navbar/navbar.component.scss
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
.navbar{
|
||||
padding-bottom: 1rem;
|
||||
}
|
||||
|
||||
.linkFix{
|
||||
text-decoration: none;
|
||||
color: white;
|
||||
}
|
||||
a{
|
||||
justify-content: left;
|
||||
}
|
||||
.login{
|
||||
justify-content: right;
|
||||
}
|
||||
.navbar-brand{
|
||||
padding-bottom: .5rem;
|
||||
}
|
||||
img{
|
||||
height: 3rem;
|
||||
margin-right: 1rem;
|
||||
border-radius: 50%;
|
||||
}
|
||||
59
src/app/components/navbar/navbar.component.spec.ts
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
import { of } from 'rxjs';
|
||||
import { AppModule } from 'src/app/app.module';
|
||||
import { Auth0Service } from 'src/app/services/auth0.service';
|
||||
|
||||
import { NavbarComponent } from './navbar.component';
|
||||
|
||||
describe('NavbarComponent', () => {
|
||||
let component: NavbarComponent;
|
||||
let fixture: ComponentFixture<NavbarComponent>;
|
||||
|
||||
let user = {
|
||||
name: "Ryon",
|
||||
email: "ryon137@gmail.com"
|
||||
};
|
||||
|
||||
const auth0Spy = jasmine.createSpyObj('Auth0Service',['getUser']);
|
||||
const getUserSpy = auth0Spy.getUser.and.returnValue(of(user));
|
||||
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
declarations: [ NavbarComponent ],
|
||||
imports: [ AppModule ],
|
||||
providers: [
|
||||
{ provide: Auth0Service, useValue: auth0Spy }
|
||||
]
|
||||
})
|
||||
.compileComponents();
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(NavbarComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should have link for Protractor', ()=>{
|
||||
const home = fixture.debugElement.nativeElement.querySelector('#home');
|
||||
expect(home.textContent).toBe("Protractor");
|
||||
});
|
||||
|
||||
it('should have link for Profile when Authenticated', ()=>{
|
||||
//need to mock authentication and create condition for when user is authenticated
|
||||
const profile = fixture.debugElement.nativeElement.querySelector('#profile');
|
||||
//expect(profile.textContent).toBe("Profile");
|
||||
});
|
||||
|
||||
it('link should navigate to / and /profile', ()=>{
|
||||
const anchorTags = fixture.debugElement.nativeElement.querySelectorAll('a');
|
||||
expect(anchorTags[0].getAttribute("routerlink")).toEqual("");
|
||||
//expect(anchorTags[1].getAttribute("routerlink")).toEqual("/profile");
|
||||
})
|
||||
|
||||
|
||||
});
|
||||
17
src/app/components/navbar/navbar.component.ts
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
import { DOCUMENT } from '@angular/common';
|
||||
import { Component, Inject, OnInit } from '@angular/core';
|
||||
import { AuthService } from '@auth0/auth0-angular';
|
||||
|
||||
@Component({
|
||||
selector: 'app-navbar',
|
||||
templateUrl: './navbar.component.html',
|
||||
styleUrls: ['./navbar.component.scss']
|
||||
})
|
||||
export class NavbarComponent implements OnInit {
|
||||
|
||||
constructor(@Inject(DOCUMENT) public document: Document, public auth: AuthService) { }
|
||||
|
||||
ngOnInit(): void {
|
||||
}
|
||||
|
||||
}
|
||||
49
src/app/components/saved-player/saved-player.component.html
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
<div class="row justify-content-center" style="margin-top: 1rem">
|
||||
<h3 id="userDetails">All Saved Matches</h3>
|
||||
</div>
|
||||
|
||||
<div id="submitButton" class="matches" *ngFor="let match of matchArray" (click)="onClick()">
|
||||
<p id="matchLabel">Match {{match.id}}</p>
|
||||
<div class="row justify-content-center" style="margin-top: 1rem" *ngIf="isPlayer == true">
|
||||
|
||||
<div class="row justify-content-center" style="margin-top: 1rem">
|
||||
|
||||
<div class="col-sm text-center">
|
||||
<p id="startTime" *ngIf="match.startTime != undefined && match.startTime != '0'">The match started
|
||||
on
|
||||
{{match.startTime}}.
|
||||
</p>
|
||||
<p id="matchDuration" *ngIf="match.durationSeconds != undefined && match.durationSeconds != '0'">It
|
||||
lasted
|
||||
{{ (match.durationSeconds / 60).toFixed(2) }} minutes.</p>
|
||||
<p id="hero" *ngIf="match.heroes != 0">You played {{ match.heroes }} <img style="width: 2rem"*ngIf="match.heroes" src="assets/heroes/{{match.heroes}}.png">.</p>
|
||||
<p id="radiant" *ngIf="match.radiant == true; else elseBlock">You were Radiant <img style="width: 2rem" src="assets/Radiant_icon.png">.</p>
|
||||
<p>
|
||||
<ng-template #elseBlock>
|
||||
<p id="dire">You were Dire <img style="width: 2rem" src="assets/Dire_icon.png">.</p>
|
||||
</ng-template>
|
||||
</p>
|
||||
<p id="firstBloodTime">First blood was achieved at {{ (match.firstBloodTime / 60).toFixed(2) }}
|
||||
minutes.
|
||||
</p>
|
||||
<p id="matchVictory" *ngIf="match.victory == true; else elseBlock2">You won.</p>
|
||||
<p>
|
||||
<ng-template #elseBlock2>
|
||||
<p id="lost">You lost.</p>
|
||||
</ng-template>
|
||||
</p>
|
||||
<p id="goldLead" *ngIf="match.largestGoldLeadTeam != undefined && match.largestGoldLead != '0'">
|
||||
{{match.largestGoldLeadTeam}} had the highest gold
|
||||
lead of
|
||||
{{match.largestGoldLead}} gold.</p>
|
||||
<p id="xpLead" *ngIf="match.largestXpLeadTeam != undefined && match.largestXpLead != '0'">
|
||||
{{match.largestXpLeadTeam}} had the highest
|
||||
experience
|
||||
lead
|
||||
of {{match.largestXpLead}} experience.</p>
|
||||
<p id="deaths" *ngIf="match.deaths != undefined">You died {{match.deaths}} times.</p>
|
||||
<p id="feed" *ngIf="match.deaths > 10">You fed.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
.matches:hover{
|
||||
cursor: pointer;
|
||||
}
|
||||
183
src/app/components/saved-player/saved-player.component.spec.ts
Normal file
|
|
@ -0,0 +1,183 @@
|
|||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
import { of } from 'rxjs';
|
||||
import { AppModule } from 'src/app/app.module';
|
||||
import { Match } from 'src/app/models/match/match.model';
|
||||
import { SavePlayerService } from 'src/app/services/save-player.service';
|
||||
|
||||
import { SavedPlayerComponent } from './saved-player.component';
|
||||
|
||||
describe('SavedPlayerComponent', () => {
|
||||
let component: SavedPlayerComponent;
|
||||
let fixture: ComponentFixture<SavedPlayerComponent>;
|
||||
|
||||
let match = new Match();
|
||||
match.id = 1;
|
||||
match.authId = [1];
|
||||
match.durationSeconds = "1";
|
||||
match.victory = true;
|
||||
match.firstBloodTime = "1";
|
||||
match.gameMode = "1";
|
||||
match.largestGoldLead = "1";
|
||||
match.largestGoldLeadTeam = "Dire";
|
||||
match.largestXpLead = "1";
|
||||
match.largestXpLeadTeam = "Radiant";
|
||||
match.startTime = "1";
|
||||
match.deaths = 11;
|
||||
match.radiant_gold_adv = [0, -34, 405, 224];
|
||||
match.radiant_xp_adv = [0, 24, 212, 211];
|
||||
match.heroes = "Mars";
|
||||
match.radiant = true;
|
||||
|
||||
let matchArray = [match];
|
||||
|
||||
const savePlayerServiceSpy = jasmine.createSpyObj('SavePlayerService',['getAllSavedMatches']);
|
||||
const getAllSavedMatchesSpy = savePlayerServiceSpy.getAllSavedMatches.and.returnValue(of(matchArray));
|
||||
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
declarations: [ SavedPlayerComponent ],
|
||||
imports: [ AppModule ],
|
||||
providers: [
|
||||
{ provide: SavePlayerService, useValue: savePlayerServiceSpy }
|
||||
]
|
||||
})
|
||||
.compileComponents();
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(SavedPlayerComponent);
|
||||
component = fixture.componentInstance;
|
||||
component.authId = 1;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
fixture.destroy();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should display All saved Matches', ()=>{
|
||||
const headerTag = fixture.debugElement.nativeElement.querySelector('#userDetails');
|
||||
expect(headerTag.textContent).toBe("All Saved Matches");
|
||||
});
|
||||
|
||||
it('should display all match ids', ()=>{
|
||||
const pTag = fixture.debugElement.nativeElement.querySelector('#matchLabel');
|
||||
expect(pTag.textContent).toBe("Match " + match.id);
|
||||
});
|
||||
|
||||
it('should display all match heroes', ()=>{
|
||||
const submitButton = fixture.debugElement.nativeElement.querySelector('#submitButton');
|
||||
|
||||
submitButton.dispatchEvent(new Event('click'));
|
||||
fixture.detectChanges();
|
||||
|
||||
const pTag = fixture.debugElement.nativeElement.querySelector('#hero');
|
||||
expect(pTag.textContent).toBe("You played " + match.heroes+" .");
|
||||
});
|
||||
|
||||
it('should display all match start times', ()=>{
|
||||
const submitButton = fixture.debugElement.nativeElement.querySelector('#submitButton');
|
||||
|
||||
submitButton.dispatchEvent(new Event('click'));
|
||||
fixture.detectChanges();
|
||||
|
||||
const pTag = fixture.debugElement.nativeElement.querySelector('#startTime');
|
||||
expect(pTag.textContent).toBe("The match started on " + match.startTime +". ");
|
||||
});
|
||||
|
||||
it('should display all match duration seconds', ()=>{
|
||||
const submitButton = fixture.debugElement.nativeElement.querySelector('#submitButton');
|
||||
|
||||
submitButton.dispatchEvent(new Event('click'));
|
||||
fixture.detectChanges();
|
||||
|
||||
const pTag = fixture.debugElement.nativeElement.querySelector('#matchDuration');
|
||||
expect(pTag.textContent).toBe("It lasted " + (match.durationSeconds / 60).toFixed(2) +" minutes.");
|
||||
});
|
||||
|
||||
it('should display all match team side if radiant', ()=>{
|
||||
const submitButton = fixture.debugElement.nativeElement.querySelector('#submitButton');
|
||||
|
||||
submitButton.dispatchEvent(new Event('click'));
|
||||
fixture.detectChanges();
|
||||
|
||||
const pTag = fixture.debugElement.nativeElement.querySelector('#radiant');
|
||||
expect(pTag.textContent).toBe("You were Radiant .");
|
||||
});
|
||||
|
||||
it('should display all match team side if dire', ()=>{
|
||||
const submitButton = fixture.debugElement.nativeElement.querySelector('#submitButton');
|
||||
|
||||
match.radiant = false;
|
||||
|
||||
submitButton.dispatchEvent(new Event('click'));
|
||||
fixture.detectChanges();
|
||||
|
||||
const pTag = fixture.debugElement.nativeElement.querySelector('#dire');
|
||||
expect(pTag.textContent).toBe("You were Dire .");
|
||||
});
|
||||
|
||||
it('should display all match first bloods', ()=>{
|
||||
const submitButton = fixture.debugElement.nativeElement.querySelector('#submitButton');
|
||||
|
||||
submitButton.dispatchEvent(new Event('click'));
|
||||
fixture.detectChanges();
|
||||
|
||||
const pTag = fixture.debugElement.nativeElement.querySelector('#firstBloodTime');
|
||||
expect(pTag.textContent).toBe("First blood was achieved at " + (match.firstBloodTime / 60).toFixed(2) +" minutes. ");
|
||||
});
|
||||
|
||||
it('should display all match victories', ()=>{
|
||||
const submitButton = fixture.debugElement.nativeElement.querySelector('#submitButton');
|
||||
|
||||
submitButton.dispatchEvent(new Event('click'));
|
||||
fixture.detectChanges();
|
||||
|
||||
const pTag = fixture.debugElement.nativeElement.querySelector('#matchVictory');
|
||||
expect(pTag.textContent).toBe("You won.");
|
||||
});
|
||||
|
||||
it('should display all gold leads', ()=>{
|
||||
const submitButton = fixture.debugElement.nativeElement.querySelector('#submitButton');
|
||||
|
||||
submitButton.dispatchEvent(new Event('click'));
|
||||
fixture.detectChanges();
|
||||
|
||||
const pTag = fixture.debugElement.nativeElement.querySelector('#goldLead');
|
||||
expect(pTag.textContent).toBe(" " + match.largestGoldLeadTeam + " had the highest gold lead of " + match.largestGoldLead + " gold.");
|
||||
});
|
||||
|
||||
it('should display all xp leads', ()=>{
|
||||
const submitButton = fixture.debugElement.nativeElement.querySelector('#submitButton');
|
||||
|
||||
submitButton.dispatchEvent(new Event('click'));
|
||||
fixture.detectChanges();
|
||||
|
||||
const pTag = fixture.debugElement.nativeElement.querySelector('#xpLead');
|
||||
expect(pTag.textContent).toBe(" " + match.largestXpLeadTeam + " had the highest experience lead of " + match.largestXpLead + " experience.");
|
||||
});
|
||||
|
||||
it('should display all deaths', ()=>{
|
||||
const submitButton = fixture.debugElement.nativeElement.querySelector('#submitButton');
|
||||
|
||||
submitButton.dispatchEvent(new Event('click'));
|
||||
fixture.detectChanges();
|
||||
|
||||
const pTag = fixture.debugElement.nativeElement.querySelector('#deaths');
|
||||
expect(pTag.textContent).toBe("You died " + match.deaths + " times.");
|
||||
});
|
||||
|
||||
it('should display hidden message if deaths are greater than 10', ()=>{
|
||||
const submitButton = fixture.debugElement.nativeElement.querySelector('#submitButton');
|
||||
|
||||
submitButton.dispatchEvent(new Event('click'));
|
||||
fixture.detectChanges();
|
||||
|
||||
const pTag = fixture.debugElement.nativeElement.querySelector('#feed');
|
||||
expect(pTag.textContent).toBe("You fed.");
|
||||
});
|
||||
});
|
||||
48
src/app/components/saved-player/saved-player.component.ts
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
import { Component, Input, OnInit } from '@angular/core';
|
||||
import { Match } from 'src/app/models/match/match.model';
|
||||
import { SavePlayerService } from 'src/app/services/save-player.service';
|
||||
import { NgbToastService } from 'ngb-toast';
|
||||
import { AuthService } from '@auth0/auth0-angular';
|
||||
import { Auth0Service } from 'src/app/services/auth0.service';
|
||||
|
||||
@Component({
|
||||
selector: 'app-saved-player',
|
||||
templateUrl: './saved-player.component.html',
|
||||
styleUrls: ['./saved-player.component.scss']
|
||||
})
|
||||
export class SavedPlayerComponent implements OnInit {
|
||||
match = new Match;
|
||||
authId!: any;
|
||||
matchArray!: Match[];
|
||||
isPlayer = false;
|
||||
|
||||
constructor(private savePlayerService: SavePlayerService, private auth: Auth0Service, private toastService: NgbToastService) { }
|
||||
|
||||
ngOnInit(): void {
|
||||
//**********************************************************/
|
||||
// Fetch this user's ID and store it locally
|
||||
//**********************************************************/
|
||||
this.auth.getUser().subscribe((data: any) => {
|
||||
if (data.sub) {
|
||||
this.authId = data.sub.substring(14, 20);
|
||||
}
|
||||
})
|
||||
/**********************************************************/
|
||||
// Loop through matches, and display any match that has this
|
||||
// user's auth ID associated with it
|
||||
//**********************************************************/
|
||||
this.savePlayerService.getAllSavedMatches().subscribe((matchArray: any) => {
|
||||
this.matchArray = [];
|
||||
for (let i = 0; i < matchArray.length; ++i) {
|
||||
if (matchArray[i].authId?.toString().includes(this.authId)) {
|
||||
this.matchArray.push(matchArray[i]);
|
||||
}
|
||||
}
|
||||
this.matchArray.reverse();
|
||||
})
|
||||
|
||||
}
|
||||
onClick() {
|
||||
this.isPlayer = true;
|
||||
}
|
||||
}
|
||||
65
src/app/components/splayer/splayer.component.html
Normal file
|
|
@ -0,0 +1,65 @@
|
|||
<div class="row justify-content-center" style="margin-top: 1rem">
|
||||
<form class="input-group input-group-lg">
|
||||
<input type="text" class="form-control input-lg" name="input" placeholder="Enter Steam ID"
|
||||
[(ngModel)]="steamid">
|
||||
<span class="input-group-btn">
|
||||
<form class="form-inline">
|
||||
<button id="submitButton" class="btn btn-outline-light" type="submit" (click)="onSubmit()"
|
||||
style="margin-left: 1rem;">Submit</button>
|
||||
</form>
|
||||
</span>
|
||||
</form>
|
||||
<div *ngIf="isPlayer == true" class="row justify-content-center" style="margin-top: 3rem">
|
||||
<div class="col-sm text-center">
|
||||
<img *ngIf="splayer" style ="padding-bottom: 1rem; width: 15rem;"src="https://steamcdn-a.akamaihd.net/steamcommunity/public/images/avatars/{{splayer.avatar}}">
|
||||
<br>
|
||||
<h1 id="playerName" *ngIf="splayer.name != undefined">{{splayer.name}}</h1>
|
||||
<p id="playerId" *ngIf="splayer.id != undefined">Steam ID: {{splayer.id}}</p>
|
||||
<p id="realName" *ngIf="splayer.realName != undefined">Real Name: {{splayer.realName}}</p>
|
||||
</div>
|
||||
|
||||
<div class="col-sm text-center">
|
||||
<h3 id="recentDetails">Most recent match details:</h3>
|
||||
<p id="matchId" *ngIf="match.id != undefined && match.id != '0'">The match id was {{match.id}}.</p>
|
||||
<p id="startTime" *ngIf="match.startTime != undefined && match.startTime != '0'">The match started on
|
||||
{{match.startTime}}.
|
||||
</p>
|
||||
<p id="matchDuration" *ngIf="match.durationSeconds != undefined && match.durationSeconds != '0'">It lasted
|
||||
{{ (match.durationSeconds / 60).toFixed(2) }} minutes.</p>
|
||||
<p id="hero" *ngIf="hero.displayName">You played {{hero.displayName}} <img style="width: 2rem" src="assets/heroes/{{hero.displayName}}.png">.</p>
|
||||
<p id="radiant" *ngIf="match.radiant == true; else elseBlock">You were Radiant <img style="width: 2rem"*ngIf="hero.displayName" src="assets/Radiant_icon.png">.</p>
|
||||
<p>
|
||||
<ng-template #elseBlock>
|
||||
<p id="dire">You were Dire <img style="width: 2rem" src="assets/Dire_icon.png">.</p>
|
||||
</ng-template>
|
||||
</p>
|
||||
<p id="firstBloodTime">First blood was achieved at {{ (match.firstBloodTime / 60).toFixed(2) }} minutes.</p>
|
||||
<p id="matchVictory" *ngIf="match.players && match.players[0].isVictory == true; else elseBlock2">You won.
|
||||
</p>
|
||||
<p>
|
||||
<ng-template #elseBlock2>
|
||||
<p id="lost">You lost.</p>
|
||||
</ng-template>
|
||||
</p>
|
||||
<p id="goldLead" *ngIf="match.largestGoldLeadTeam != undefined && match.largestGoldLead != '0'">
|
||||
{{match.largestGoldLeadTeam}} had the highest gold
|
||||
lead of
|
||||
{{match.largestGoldLead}} gold.</p>
|
||||
<p id="xpLead" *ngIf="match.largestXpLeadTeam != undefined && match.largestXpLead != '0'">
|
||||
{{match.largestXpLeadTeam}} had the highest
|
||||
experience
|
||||
lead
|
||||
of {{match.largestXpLead}} experience.</p>
|
||||
<p id="deaths" *ngIf="match.deaths != undefined">You died {{match.deaths}} times.</p>
|
||||
<p id="feed" *ngIf="match.deaths > 10">You fed.</p>
|
||||
</div>
|
||||
</div>
|
||||
<img id="protractor" *ngIf="isPlayer == false" src="favicon.ico" style="padding-top: 2rem; padding-bottom: 1rem; width: 15rem;">
|
||||
</div>
|
||||
<div *ngIf="isPlayer == true && data != null">
|
||||
<div class="row justify-content-center" style="margin-top: 3rem">
|
||||
<button id="saveMatchButton" class="btn btn-outline-light" type="submit" (click)="onSubmit2()"
|
||||
style="width: 10rem;">Save
|
||||
Match</button>
|
||||
</div>
|
||||
</div>
|
||||
14
src/app/components/splayer/splayer.component.scss
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
h3{
|
||||
padding-bottom: 1rem;
|
||||
}
|
||||
h1{
|
||||
padding-bottom: 1rem;
|
||||
}
|
||||
p{
|
||||
font-size: 18px;
|
||||
}
|
||||
|
||||
button{
|
||||
//margin-left: 1rem;
|
||||
margin-top: .25rem;
|
||||
}
|
||||
324
src/app/components/splayer/splayer.component.spec.ts
Normal file
|
|
@ -0,0 +1,324 @@
|
|||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
import { NgbToast, NgbToastService } from 'ngb-toast';
|
||||
import { of } from 'rxjs';
|
||||
import { AppModule } from 'src/app/app.module';
|
||||
import { Hero } from 'src/app/models/hero/hero.model';
|
||||
import { Match } from 'src/app/models/match/match.model';
|
||||
import { SPlayer } from 'src/app/models/s-player/splayer.model';
|
||||
import { OpendotaService } from 'src/app/services/opendota.service';
|
||||
import { SavePlayerService } from 'src/app/services/save-player.service';
|
||||
import { StratzService } from 'src/app/services/stratz.service';
|
||||
|
||||
import { SplayerComponent } from './splayer.component';
|
||||
|
||||
describe('SplayerComponent', () => {
|
||||
let component: SplayerComponent;
|
||||
let fixture: ComponentFixture<SplayerComponent>;
|
||||
|
||||
let steamid = '66914827';
|
||||
|
||||
let hero = new Hero();
|
||||
hero.displayName = "Outworld Destroyer";
|
||||
hero.id = 76;
|
||||
let hero2 = new Hero();
|
||||
hero2.id = 11;
|
||||
hero2.displayName = "Mars";
|
||||
|
||||
let heroArray = [hero, hero2];
|
||||
|
||||
let match = new Match();
|
||||
match.id = 1;
|
||||
match.authId = [1,2,3];
|
||||
match.durationSeconds = "1";
|
||||
match.victory = true;
|
||||
match.players = [{isVictory!: true, heroId!: 11, isRadiant!: true}]
|
||||
match.firstBloodTime = "1";
|
||||
match.gameMode = "1";
|
||||
match.largestGoldLead = "1";
|
||||
match.largestGoldLeadTeam = "Dire";
|
||||
match.largestXpLead = "1";
|
||||
match.largestXpLeadTeam = "Radiant";
|
||||
match.startTime = "1";
|
||||
match.deaths = 11;
|
||||
match.radiant_gold_adv = [0, -34, 405, 224];
|
||||
match.radiant_xp_adv = [0, 24, 212, 211];
|
||||
match.heroes = "Outworld Destroyer";
|
||||
match.radiant = true;
|
||||
|
||||
let matchArray = [match];
|
||||
|
||||
let player = new SPlayer();
|
||||
player.name = "Ryon";
|
||||
player.id = 1;
|
||||
player.realName = "Real Ryon";
|
||||
player.avatar = "link";
|
||||
player.profileUri = "uri";
|
||||
player.matchesList = [match];
|
||||
|
||||
let user = {
|
||||
name: "Ryon",
|
||||
email: "ryon137@gmail.com",
|
||||
authId: 'aaa'
|
||||
};
|
||||
|
||||
const stratzServiceSpy = jasmine.createSpyObj('StratzService',[
|
||||
'getPlayer', 'getPlayerMatches', 'getHero']);
|
||||
const getPlayerSpy = stratzServiceSpy.getPlayer.and.returnValue(of(player));
|
||||
const getPlayerMatchesSpy = stratzServiceSpy.getPlayerMatches.and.returnValue(of(matchArray));
|
||||
const getHeroSpy = stratzServiceSpy.getHero.and.returnValue(of(heroArray));
|
||||
|
||||
const savePlayerServiceSpy = jasmine.createSpyObj('SavePlayerService',[
|
||||
'getAllSavedMatches', 'addMatch', 'getSavedPlayerById']);
|
||||
const getAllSavedMatchesSpy = savePlayerServiceSpy.getAllSavedMatches.and.returnValue(of(match));
|
||||
const addMatchSpy = savePlayerServiceSpy.addMatch.and.returnValue(of(match));
|
||||
const getSavedPlayerByIdSpy = savePlayerServiceSpy.getSavedPlayerById.and.returnValue(of(player));
|
||||
|
||||
const opendotaServiceSpy = jasmine.createSpyObj('OpendotaService',['getMatch']);
|
||||
const getMatchSpy = opendotaServiceSpy.getMatch.and.returnValue(of(match));
|
||||
|
||||
const auth0Spy = jasmine.createSpyObj('Auth0Service',['getUser']);
|
||||
const getUserSpy = auth0Spy.getUser.and.returnValue(of(user));
|
||||
|
||||
const toastSpy = jasmine.createSpyObj('NgbToastService',['remove','show']);
|
||||
const removeSpy = toastSpy.remove.and.returnValue(of(new NgbToast));
|
||||
const showSpy = toastSpy.show.and.returnValue(of(new NgbToast));
|
||||
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
declarations: [ SplayerComponent ],
|
||||
imports: [ AppModule ],
|
||||
providers: [
|
||||
{ provide: StratzService, useValue: stratzServiceSpy },
|
||||
{ provide: SavePlayerService, useValue: savePlayerServiceSpy },
|
||||
{ provide: OpendotaService, useValue: opendotaServiceSpy },
|
||||
{ provide: NgbToastService, useValue: toastSpy },
|
||||
{ provide: steamid, useValue: '66914827' }
|
||||
]
|
||||
})
|
||||
.compileComponents();
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(SplayerComponent);
|
||||
component = fixture.componentInstance;
|
||||
component.steamid = steamid;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
fixture.destroy();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should display the player name when submit button is clicked and steamid is provided', ()=>{
|
||||
const submitButton = fixture.debugElement.nativeElement.querySelector('#submitButton');
|
||||
|
||||
submitButton.dispatchEvent(new Event('click'));
|
||||
fixture.detectChanges();
|
||||
|
||||
const headerTag = fixture.debugElement.nativeElement.querySelector('#playerName');
|
||||
expect(headerTag.textContent).toBe(player.name);
|
||||
});
|
||||
|
||||
it('should display the player id when submit button is clicked and steamid is provided', ()=>{
|
||||
const submitButton = fixture.debugElement.nativeElement.querySelector('#submitButton');
|
||||
|
||||
submitButton.dispatchEvent(new Event('click'));
|
||||
fixture.detectChanges();
|
||||
|
||||
const headerTag = fixture.debugElement.nativeElement.querySelector('#playerId');
|
||||
expect(headerTag.textContent).toBe("Steam ID: " + player.id);
|
||||
});
|
||||
|
||||
it('should display the player real name when submit button is clicked and steamid is provided', ()=>{
|
||||
const submitButton = fixture.debugElement.nativeElement.querySelector('#submitButton');
|
||||
|
||||
submitButton.dispatchEvent(new Event('click'));
|
||||
fixture.detectChanges();
|
||||
|
||||
const headerTag = fixture.debugElement.nativeElement.querySelector('#realName');
|
||||
expect(headerTag.textContent).toBe("Real Name: " + player.realName);
|
||||
});
|
||||
|
||||
it('should display most recent match details when submit button is clicked and steamid is provided', ()=>{
|
||||
const submitButton = fixture.debugElement.nativeElement.querySelector('#submitButton');
|
||||
|
||||
submitButton.dispatchEvent(new Event('click'));
|
||||
fixture.detectChanges();
|
||||
|
||||
const headerTag = fixture.debugElement.nativeElement.querySelector('#recentDetails');
|
||||
expect(headerTag.textContent).toBe("Most recent match details:");
|
||||
});
|
||||
|
||||
|
||||
it('should display the match id when submit button is clicked and steamid is provided', ()=>{
|
||||
const submitButton = fixture.debugElement.nativeElement.querySelector('#submitButton');
|
||||
|
||||
submitButton.dispatchEvent(new Event('click'));
|
||||
fixture.detectChanges();
|
||||
|
||||
const headerTag = fixture.debugElement.nativeElement.querySelector('#matchId');
|
||||
expect(headerTag.textContent).toBe("The match id was " + match.id + ".");
|
||||
});
|
||||
|
||||
it('should display the match duration when submit button is clicked and steamid is provided', ()=>{
|
||||
const submitButton = fixture.debugElement.nativeElement.querySelector('#submitButton');
|
||||
|
||||
submitButton.dispatchEvent(new Event('click'));
|
||||
fixture.detectChanges();
|
||||
|
||||
const headerTag = fixture.debugElement.nativeElement.querySelector('#matchDuration');
|
||||
expect(headerTag.textContent).toBe("It lasted " + (match.durationSeconds / 60).toFixed(2) + " minutes.");
|
||||
});
|
||||
|
||||
it('should display the hero when submit button is clicked and steamid is provided', ()=>{
|
||||
const submitButton = fixture.debugElement.nativeElement.querySelector('#submitButton');
|
||||
|
||||
submitButton.dispatchEvent(new Event('click'));
|
||||
fixture.detectChanges();
|
||||
|
||||
const headerTag = fixture.debugElement.nativeElement.querySelector('#hero');
|
||||
expect(headerTag.textContent).toBe("You played " + hero2.displayName + " .");
|
||||
});
|
||||
|
||||
it('should display the radiant played when submit button is clicked and steamid is provided', ()=>{
|
||||
const submitButton = fixture.debugElement.nativeElement.querySelector('#submitButton');
|
||||
|
||||
submitButton.dispatchEvent(new Event('click'));
|
||||
fixture.detectChanges();
|
||||
|
||||
const headerTag = fixture.debugElement.nativeElement.querySelector('#radiant');
|
||||
expect(headerTag.textContent).toBe("You were Radiant .");
|
||||
});
|
||||
|
||||
it('should display the radiant played when submit button is clicked and steamid is provided', ()=>{
|
||||
const submitButton = fixture.debugElement.nativeElement.querySelector('#submitButton');
|
||||
|
||||
submitButton.dispatchEvent(new Event('click'));
|
||||
match.radiant = false;
|
||||
fixture.detectChanges();
|
||||
|
||||
const headerTag = fixture.debugElement.nativeElement.querySelector('#dire');
|
||||
expect(headerTag.textContent).toBe("You were Dire .");
|
||||
});
|
||||
|
||||
it('should display the first blood time when submit button is clicked and steamid is provided', ()=>{
|
||||
const submitButton = fixture.debugElement.nativeElement.querySelector('#submitButton');
|
||||
|
||||
submitButton.dispatchEvent(new Event('click'));
|
||||
fixture.detectChanges();
|
||||
|
||||
const headerTag = fixture.debugElement.nativeElement.querySelector('#firstBloodTime');
|
||||
expect(headerTag.textContent).toBe("First blood was achieved at " + (match.firstBloodTime / 60).toFixed(2) + " minutes.");
|
||||
});
|
||||
|
||||
it('should display victory when submit button is clicked and steamid is provided and victory is true', ()=>{
|
||||
const submitButton = fixture.debugElement.nativeElement.querySelector('#submitButton');
|
||||
|
||||
submitButton.dispatchEvent(new Event('click'));
|
||||
fixture.detectChanges();
|
||||
|
||||
const headerTag = fixture.debugElement.nativeElement.querySelector('#matchVictory');
|
||||
|
||||
expect(headerTag.textContent).toBe("You won. ");
|
||||
|
||||
});
|
||||
|
||||
it('should display largest gold lead and corresponding team when submit button is clicked and steamid is provided', ()=>{
|
||||
const submitButton = fixture.debugElement.nativeElement.querySelector('#submitButton');
|
||||
|
||||
submitButton.dispatchEvent(new Event('click'));
|
||||
fixture.detectChanges();
|
||||
|
||||
const goldLead = fixture.debugElement.nativeElement.querySelector('#goldLead');
|
||||
|
||||
expect(goldLead.textContent).toBe(" " + match.largestGoldLeadTeam + " had the highest gold lead of " + match.largestGoldLead + " gold.");
|
||||
|
||||
});
|
||||
|
||||
it('should display largest xp lead and corresponding team when submit button is clicked and steamid is provided', ()=>{
|
||||
const submitButton = fixture.debugElement.nativeElement.querySelector('#submitButton');
|
||||
|
||||
submitButton.dispatchEvent(new Event('click'));
|
||||
fixture.detectChanges();
|
||||
|
||||
const goldLead = fixture.debugElement.nativeElement.querySelector('#xpLead');
|
||||
|
||||
expect(goldLead.textContent).toBe(" " + match.largestXpLeadTeam + " had the highest experience lead of " + match.largestXpLead + " experience.");
|
||||
|
||||
});
|
||||
|
||||
it('should display the start time when submit button is clicked and steamid is provided', ()=>{
|
||||
const submitButton = fixture.debugElement.nativeElement.querySelector('#submitButton');
|
||||
|
||||
submitButton.dispatchEvent(new Event('click'));
|
||||
fixture.detectChanges();
|
||||
const headerTag = fixture.debugElement.nativeElement.querySelector('#startTime');
|
||||
expect(headerTag.textContent).toBe("The match started on " + match.startTime + ". ");
|
||||
|
||||
});
|
||||
|
||||
it('should display the deaths when submit button is clicked and steamid is provided', ()=>{
|
||||
const submitButton = fixture.debugElement.nativeElement.querySelector('#submitButton');
|
||||
|
||||
submitButton.dispatchEvent(new Event('click'));
|
||||
fixture.detectChanges();
|
||||
const headerTag = fixture.debugElement.nativeElement.querySelector('#deaths');
|
||||
expect(headerTag.textContent).toBe("You died " + match.deaths + " times.");
|
||||
|
||||
});
|
||||
|
||||
it('should display the special message when submit button is clicked and steamid is provided and deaths are greater than 10', ()=>{
|
||||
const submitButton = fixture.debugElement.nativeElement.querySelector('#submitButton');
|
||||
|
||||
submitButton.dispatchEvent(new Event('click'));
|
||||
fixture.detectChanges();
|
||||
const headerTag = fixture.debugElement.nativeElement.querySelector('#feed');
|
||||
expect(headerTag.textContent).toBe("You fed.");
|
||||
});
|
||||
|
||||
it('should display logo when no id is provided', ()=>{
|
||||
|
||||
const headerTag = fixture.debugElement.nativeElement.querySelector('#protractor');
|
||||
expect(headerTag['src']).toContain('favicon.ico');
|
||||
|
||||
});
|
||||
|
||||
it('should display save button when logged in', ()=>{
|
||||
component.isPlayer = true;
|
||||
component.data = 'a';
|
||||
fixture.detectChanges();
|
||||
|
||||
const saveMatch = fixture.debugElement.nativeElement.querySelector('#saveMatchButton');
|
||||
expect(saveMatch.textContent).toBe("Save Match");
|
||||
|
||||
});
|
||||
|
||||
it('if onSubmit is called and steamId does not fit the regex, showFailure should be called', ()=>{
|
||||
component.onSubmit();
|
||||
component.steamid = ' ';
|
||||
component.showFailure();
|
||||
expect(showSpy).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('if steamId is the larger format, number should be converted and showConversion should be called', ()=>{
|
||||
component.steamid = '76561198066745404';
|
||||
component.largeId = 99999999999n;
|
||||
component.conversionNum = 76561197960265728n;
|
||||
component.onSubmit();
|
||||
expect(showSpy).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('if onSubmit2 is called, expect getSavedPlayerById to be called', ()=>{
|
||||
component.onSubmit2();
|
||||
expect(getSavedPlayerByIdSpy).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('if onSubmit2 is called, expect addMatch to be called', ()=>{
|
||||
component.onSubmit2();
|
||||
expect(addMatchSpy).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
99
src/app/components/splayer/splayer.component.test2.spec.ts
Normal file
|
|
@ -0,0 +1,99 @@
|
|||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
import { NgbToast, NgbToastService } from 'ngb-toast';
|
||||
import { of } from 'rxjs';
|
||||
import { AppModule } from 'src/app/app.module';
|
||||
import { Hero } from 'src/app/models/hero/hero.model';
|
||||
import { Match } from 'src/app/models/match/match.model';
|
||||
import { SPlayer } from 'src/app/models/s-player/splayer.model';
|
||||
import { OpendotaService } from 'src/app/services/opendota.service';
|
||||
import { SavePlayerService } from 'src/app/services/save-player.service';
|
||||
import { StratzService } from 'src/app/services/stratz.service';
|
||||
|
||||
import { SplayerComponent } from './splayer.component';
|
||||
|
||||
describe('SplayerComponent', () => {
|
||||
let component: SplayerComponent;
|
||||
let fixture: ComponentFixture<SplayerComponent>;
|
||||
|
||||
let steamid = '66914827';
|
||||
|
||||
let hero = new Hero();
|
||||
hero.displayName = "Outworld Destroyer";
|
||||
hero.id = 76;
|
||||
let hero2 = new Hero();
|
||||
hero2.id = 11;
|
||||
hero2.displayName = "Mars";
|
||||
|
||||
let heroArray = [hero, hero2];
|
||||
|
||||
let match = new Match();
|
||||
match.id = 1;
|
||||
match.authId = [1,2,3];
|
||||
match.durationSeconds = "1";
|
||||
match.victory = true;
|
||||
match.players = [{isVictory!: true, heroId!: 11}]
|
||||
match.firstBloodTime = "1";
|
||||
match.gameMode = "1";
|
||||
match.largestGoldLead = "1";
|
||||
match.largestGoldLeadTeam = "Dire";
|
||||
match.largestXpLead = "1";
|
||||
match.largestXpLeadTeam = "Radiant";
|
||||
match.startTime = "1";
|
||||
match.deaths = 11;
|
||||
match.radiant_gold_adv = [0, -34, 405, 224];
|
||||
match.radiant_xp_adv = [0, 24, 212, 211];
|
||||
match.heroes = "Outworld Destroyer";
|
||||
|
||||
let matchArray = [match];
|
||||
|
||||
let player = null;
|
||||
|
||||
let user = {
|
||||
name: "Ryon",
|
||||
email: "ryon137@gmail.com",
|
||||
authId: 'aaa'
|
||||
};
|
||||
|
||||
const stratzServiceSpy = jasmine.createSpyObj('StratzService',[
|
||||
'getPlayer', 'getPlayerMatches', 'getHero']);
|
||||
const getPlayerSpy = stratzServiceSpy.getPlayer.and.returnValue(of(player));
|
||||
const getPlayerMatchesSpy = stratzServiceSpy.getPlayerMatches.and.returnValue(of(matchArray));
|
||||
const getHeroSpy = stratzServiceSpy.getHero.and.returnValue(of(heroArray));
|
||||
|
||||
const auth0Spy = jasmine.createSpyObj('Auth0Service',['getUser']);
|
||||
const getUserSpy = auth0Spy.getUser.and.returnValue(of(user));
|
||||
|
||||
const toastSpy = jasmine.createSpyObj('NgbToastService',['remove','show']);
|
||||
const removeSpy = toastSpy.remove.and.returnValue(of(new NgbToast));
|
||||
const showSpy = toastSpy.show.and.returnValue(of(new NgbToast));
|
||||
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
declarations: [ SplayerComponent ],
|
||||
imports: [ AppModule ],
|
||||
providers: [
|
||||
{ provide: StratzService, useValue: stratzServiceSpy },
|
||||
{ provide: NgbToastService, useValue: toastSpy },
|
||||
{ provide: steamid, useValue: '66914827' }
|
||||
]
|
||||
})
|
||||
.compileComponents();
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(SplayerComponent);
|
||||
component = fixture.componentInstance;
|
||||
component.steamid = steamid;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
fixture.destroy();
|
||||
});
|
||||
|
||||
it('if getPlayer returns null, then player does not exist', ()=>{
|
||||
component.onSubmit();
|
||||
expect(component.isPlayer).toBeFalse();
|
||||
});
|
||||
|
||||
});
|
||||
337
src/app/components/splayer/splayer.component.ts
Normal file
|
|
@ -0,0 +1,337 @@
|
|||
import { DOCUMENT } from '@angular/common';
|
||||
import { Component, Inject, OnInit } from '@angular/core';
|
||||
import { AuthService } from '@auth0/auth0-angular';
|
||||
import { Match } from 'src/app/models/match/match.model';
|
||||
import { SPlayer } from 'src/app/models/s-player/splayer.model';
|
||||
import { OpendotaService } from 'src/app/services/opendota.service';
|
||||
import { SavePlayerService } from 'src/app/services/save-player.service';
|
||||
import { StratzService } from 'src/app/services/stratz.service';
|
||||
import { NgbToast, NgbToastService, NgbToastType } from 'ngb-toast';
|
||||
import { Hero } from 'src/app/models/hero/hero.model';
|
||||
import { Auth0Service } from 'src/app/services/auth0.service';
|
||||
@Component({
|
||||
selector: 'app-splayer',
|
||||
templateUrl: './splayer.component.html',
|
||||
styleUrls: ['./splayer.component.scss']
|
||||
})
|
||||
//***********************************************************************************/
|
||||
// This class retrieves data from various API's based on given steam ID, and displays.
|
||||
// It also saves the given match and player. If a player already exists, it adds the
|
||||
// match data to that player
|
||||
//***********************************************************************************/
|
||||
export class SplayerComponent implements OnInit {
|
||||
splayer = new SPlayer;
|
||||
match = new Match;
|
||||
match2 = new Match;
|
||||
steamid = '';
|
||||
isPlayer = false; //flag for displaying logo
|
||||
regex = /[0-9]{8}$/;
|
||||
largeId = 99999999999n;
|
||||
conversionNum = 76561197960265728n;
|
||||
hero = new Hero;
|
||||
data!: any;
|
||||
|
||||
constructor(private savePlayerService: SavePlayerService, private stratzService: StratzService, private opendotaService: OpendotaService, @Inject(DOCUMENT) public document: Document, public auth: Auth0Service, private toastService: NgbToastService) {
|
||||
}
|
||||
|
||||
onSubmit() {
|
||||
//**********************************************************/
|
||||
// Form validation
|
||||
//**********************************************************/
|
||||
if (!this.regex.test(this.steamid)) {
|
||||
this.showFailure();
|
||||
return;
|
||||
}
|
||||
//**********************************************************/
|
||||
// Convert steamId to proper format
|
||||
//**********************************************************/
|
||||
if (BigInt(this.steamid) > this.largeId) {
|
||||
this.steamid = (BigInt(this.steamid) - this.conversionNum).toString();
|
||||
this.steamid.slice(0, 7);
|
||||
this.showConversion();
|
||||
}
|
||||
this.isPlayer = true;
|
||||
//**********************************************************/
|
||||
// Gets player details and stores them in SPlayer model
|
||||
//**********************************************************/
|
||||
this.stratzService.getPlayer(this.steamid).subscribe((Player: any) => {
|
||||
//if player is null, do not show details, and show error toast
|
||||
if (Player == null) {
|
||||
this.isPlayer = false;
|
||||
this.showInvalidIdFailure();
|
||||
return;
|
||||
}
|
||||
this.splayer = Player;
|
||||
this.splayer.name = Player.steamAccount.name;
|
||||
this.splayer.id = Player.steamAccount.id;
|
||||
this.splayer.realName = Player.steamAccount.realName;
|
||||
this.splayer.avatar = Player.steamAccount.avatar;
|
||||
this.splayer.profileUri = Player.steamAccount.profileUri;
|
||||
}),
|
||||
//**********************************************************/
|
||||
// Gets 10 most recent matches and stores them all in Matches Model
|
||||
//**********************************************************/
|
||||
this.stratzService.getPlayerMatches(this.steamid).subscribe((match: any) => {
|
||||
//add match information to match object
|
||||
for (let i = 0; i <= 10; ++i) {
|
||||
if (match[i]?.id !== undefined) {
|
||||
this.match = match[i];
|
||||
|
||||
//**********************************************************/
|
||||
//Start time
|
||||
//**********************************************************/
|
||||
|
||||
let a = new Date(match[i]?.startDateTime * 1000);
|
||||
let months = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'];
|
||||
let year = a.getFullYear();
|
||||
let month = months[a.getMonth()];
|
||||
let date = a.getDate();
|
||||
let hour = a.getHours();
|
||||
let minutes = a.getMinutes();
|
||||
let seconds = a.getSeconds();
|
||||
let formattedTime = month + ' ' + date + ', ' + year + ' at ' + hour + ':' + minutes + ':' + seconds;
|
||||
this.match.startTime = formattedTime;
|
||||
|
||||
//**********************************************************/
|
||||
//Hero ID, Victory, and isRadiant
|
||||
//**********************************************************/
|
||||
this.match.heroes = this.match.players[0].heroId;
|
||||
this.match.victory = this.match.players[0].isVictory;
|
||||
this.match.radiant = this.match.players[0].isRadiant;
|
||||
|
||||
//**********************************************************/
|
||||
// Searches the API for the given hero ID and then stores the hero data
|
||||
//**********************************************************/
|
||||
this.stratzService.getHero().subscribe((heroes: any) => {
|
||||
for (let i = 1; i <= Object.keys(heroes).length; ++i) {
|
||||
if (heroes[i]?.id !== undefined) {
|
||||
if (heroes[i]?.id == this.match.heroes) {
|
||||
this.hero.id = heroes[i].id;
|
||||
this.hero.displayName = heroes[i].displayName;
|
||||
this.match.heroes = this.hero.displayName;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
//**********************************************************/
|
||||
// Gets more match data on given match id from OpenDota API
|
||||
//**********************************************************/
|
||||
this.opendotaService.getMatch(this.match.id).subscribe((match: any) => {
|
||||
//**********************************************************/
|
||||
//Gold lead
|
||||
//**********************************************************/
|
||||
let radiantGoldLead = 0;
|
||||
let direGoldLead = 0;
|
||||
|
||||
for (let j = 0; j < match?.radiant_gold_adv?.length; ++j) {
|
||||
if (match.radiant_gold_adv[j] >= 0 && match.radiant_gold_adv[j] > radiantGoldLead) {
|
||||
radiantGoldLead = match.radiant_gold_adv[j];
|
||||
}
|
||||
else {
|
||||
if (match.radiant_gold_adv[j] < direGoldLead) {
|
||||
direGoldLead = match.radiant_gold_adv[j];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (Math.abs(radiantGoldLead) > Math.abs(direGoldLead)) {
|
||||
this.match.largestGoldLead = Math.abs(radiantGoldLead);
|
||||
this.match.largestGoldLeadTeam = "Radiant";
|
||||
}
|
||||
else {
|
||||
this.match.largestGoldLead = Math.abs(direGoldLead);
|
||||
this.match.largestGoldLeadTeam = "Dire";
|
||||
}
|
||||
|
||||
//**********************************************************/
|
||||
//XP lead
|
||||
//**********************************************************/
|
||||
let radiantXpLead = 0;
|
||||
let direXpLead = 0;
|
||||
|
||||
for (let j = 0; j < match?.radiant_xp_adv?.length; ++j) {
|
||||
if (match.radiant_xp_adv[j] > 0) {
|
||||
if (match.radiant_xp_adv[j] > radiantXpLead) {
|
||||
radiantXpLead = match.radiant_xp_adv[j];
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (match.radiant_xp_adv[j] < direXpLead) {
|
||||
direXpLead = match.radiant_xp_adv[j];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (Math.abs(radiantXpLead) > Math.abs(direXpLead)) {
|
||||
this.match.largestXpLead = Math.abs(radiantXpLead);
|
||||
this.match.largestXpLeadTeam = "Radiant";
|
||||
}
|
||||
else {
|
||||
this.match.largestXpLead = Math.abs(direXpLead);
|
||||
this.match.largestXpLeadTeam = "Dire";
|
||||
}
|
||||
//**********************************************************/
|
||||
//Deaths
|
||||
//**********************************************************/
|
||||
for (let j = 0; j < match.players.length; ++j) {
|
||||
if(match.players[j].account_id && match.players[j].account_id == this.steamid) {
|
||||
this.match.deaths = match.players[j].deaths;
|
||||
}
|
||||
}
|
||||
});
|
||||
break;
|
||||
//heroes, kills, deaths, assists, last hits, denies, GPM, EXPM, level, gold, goldspent, hero damage, tower damage, lane, role, items, backpack, hero healing, networth, neutral item
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
//initilize values if they dont exist so posting works
|
||||
if (this.match.id == undefined) {
|
||||
this.match.id = 0;
|
||||
}
|
||||
if (this.match.durationSeconds == undefined) {
|
||||
this.match.durationSeconds = "0";
|
||||
}
|
||||
if (this.match.victory == undefined) {
|
||||
this.match.victory = false;
|
||||
}
|
||||
if (this.match.firstBloodTime == undefined) {
|
||||
this.match.firstBloodTime = "0";
|
||||
}
|
||||
if (this.match.gameMode == undefined) {
|
||||
this.match.gameMode = "0";
|
||||
}
|
||||
if (this.match.heroes == undefined) {
|
||||
this.match.heroes = "0";
|
||||
}
|
||||
if (this.match.largestGoldLead == undefined) {
|
||||
this.match.largestGoldLead = "0";
|
||||
}
|
||||
if (this.match.largestGoldLeadTeam == undefined) {
|
||||
this.match.largestGoldLeadTeam = "0";
|
||||
}
|
||||
if (this.match.largestXpLead == undefined) {
|
||||
this.match.largestXpLead = "0";
|
||||
}
|
||||
if (this.match.largestXpLeadTeam == undefined) {
|
||||
this.match.largestXpLeadTeam = "0";
|
||||
}
|
||||
if (this.match.startTime == undefined) {
|
||||
this.match.startTime = "0";
|
||||
}
|
||||
if (this.match.deaths == undefined || this.match.deaths == null) {
|
||||
this.match.deaths = 0;
|
||||
}
|
||||
|
||||
//**********************************************************/
|
||||
// Store authentication ID in model for future reference
|
||||
//**********************************************************/
|
||||
this.auth.getUser().subscribe((data: any) => {
|
||||
//to check if user exists
|
||||
this.data = data;
|
||||
if (this.match.authId == null) {
|
||||
this.match.authId = [];
|
||||
}
|
||||
if (data) {
|
||||
this.match.authId.push(data.sub.substring(14, 20));
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
|
||||
}
|
||||
//**********************************************************/
|
||||
// Saves match and player to database
|
||||
//**********************************************************/
|
||||
onSubmit2() {
|
||||
let matchFound = false;
|
||||
|
||||
this.savePlayerService.getSavedPlayerById(this.steamid).subscribe((player: any) => {
|
||||
this.splayer.matchesList = player?.matchesList;
|
||||
//intilize match list if not already created
|
||||
if (this.splayer.matchesList == null) {
|
||||
this.splayer.matchesList = [];
|
||||
}
|
||||
//if the id is in the match array, set match found to true
|
||||
//CURRENT BUG: If the match id is the same, a different players match
|
||||
// will overwrite current match
|
||||
//
|
||||
//SOLUTION: make it so that if the match id already exists,
|
||||
// create a new instance
|
||||
//
|
||||
for (let i = 0; i < Object.keys(this.splayer.matchesList).length; ++i) {
|
||||
if (this.splayer.matchesList[i].id == this.match.id) {
|
||||
matchFound = true;
|
||||
}
|
||||
}
|
||||
//add match to match array if match was not found in match array
|
||||
if (matchFound == false) {
|
||||
this.splayer.matchesList.push(this.match);
|
||||
}
|
||||
this.savePlayerService.addMatch(this.match, this.splayer);
|
||||
});
|
||||
}
|
||||
//**********************************************************/
|
||||
// Toast for id being too small
|
||||
//**********************************************************/
|
||||
showFailure(): void {
|
||||
const toast: NgbToast = {
|
||||
toastType: NgbToastType.Danger,
|
||||
text: "ID must be at least 8 digits",
|
||||
dismissible: true,
|
||||
timeInSeconds: 5,
|
||||
onDismiss: () => {
|
||||
console.log("Toast dismissed!!");
|
||||
}
|
||||
}
|
||||
this.toastService.show(toast);
|
||||
}
|
||||
//**********************************************************/
|
||||
// Toast for player not existing
|
||||
//**********************************************************/
|
||||
showInvalidIdFailure(): void {
|
||||
const toast: NgbToast = {
|
||||
toastType: NgbToastType.Danger,
|
||||
text: "Either user does not exist, or their profile is hidden",
|
||||
dismissible: true,
|
||||
timeInSeconds: 5,
|
||||
onDismiss: () => {
|
||||
console.log("Toast dismissed!!");
|
||||
}
|
||||
}
|
||||
this.toastService.show(toast);
|
||||
}
|
||||
//**********************************************************/
|
||||
// Toast for id conversion
|
||||
//**********************************************************/
|
||||
showConversion(): void {
|
||||
const toast: NgbToast = {
|
||||
toastType: NgbToastType.Info,
|
||||
text: "ID converted to correct format",
|
||||
dismissible: true,
|
||||
timeInSeconds: 5,
|
||||
onDismiss: () => {
|
||||
console.log("Toast dismissed!!");
|
||||
}
|
||||
}
|
||||
this.toastService.show(toast);
|
||||
}
|
||||
//**********************************************************/
|
||||
// Remove toast
|
||||
//**********************************************************/
|
||||
removeToast(toast: NgbToast): void {
|
||||
this.toastService.remove(toast);
|
||||
}
|
||||
|
||||
ngOnInit(): void {
|
||||
|
||||
}
|
||||
}
|
||||
//
|
||||
// TEST ID's
|
||||
// 83177429
|
||||
// 64819449
|
||||
// 132407154
|
||||
// 76561198066745404
|
||||
//
|
||||
78
src/app/components/user-profile/user-profile.component.html
Normal file
|
|
@ -0,0 +1,78 @@
|
|||
<ul>
|
||||
<div *ngIf="playerExists == false && authentication.getUser">
|
||||
<div class="row justify-content-center" style="margin-top: 1rem">
|
||||
<h3 id="userDetails">Enter your Steam ID</h3>
|
||||
</div>
|
||||
<form class="input-group input-group-lg">
|
||||
<input type="text" class="form-control input-lg" name="input" placeholder="Enter Steam ID" [(ngModel)]="steamId">
|
||||
<span class="input-group-btn">
|
||||
<form class="form-inline">
|
||||
<button id="submitButton" class="btn btn-outline-light" type="submit" (click)="onSubmit()"
|
||||
style="margin-left: 1rem;">Submit</button>
|
||||
</form>
|
||||
</span>
|
||||
</form>
|
||||
</div>
|
||||
<div class="row justify-content-center" style="margin-top: 1rem">
|
||||
<div class="col-sm text-center">
|
||||
<h3 id="userDetails">Account Information</h3>
|
||||
<br>
|
||||
<button *ngIf="playerExists == true" id="changeIdButton" class="btn btn-outline-light" type="submit"
|
||||
(click)="onClick2()">Change Steam ID</button>
|
||||
</div>
|
||||
</div>
|
||||
<p id="userName" *ngIf="data">User Name: {{ data.name }}</p>
|
||||
<p id="userEmail" *ngIf="data">User Email: {{ data.email }}</p>
|
||||
<p id="playerId" *ngIf="playerId">Steam ID: {{playerId}}</p>
|
||||
<div *ngIf="playerExists == true">
|
||||
<div class="col-sm text-center">
|
||||
<img id="image" *ngIf="player"
|
||||
src="https://steamcdn-a.akamaihd.net/steamcommunity/public/images/avatars/{{player.avatar}}">
|
||||
<br><br>
|
||||
<h1 id="playerName" *ngIf="player">{{player.name}}'s Saved Matches</h1>
|
||||
</div>
|
||||
<div class="matches" *ngFor="let match of player?.matchesList" (click)="onClick()">
|
||||
<p id="matchId">Match {{match.id}}</p>
|
||||
<div class="row justify-content-center" style="margin-top: 1rem" *ngIf="isPlayer == true">
|
||||
|
||||
<div class="row justify-content-center" style="margin-top: 1rem">
|
||||
|
||||
<div class="col-sm text-center">
|
||||
<p id="startTime" *ngIf="match.startTime != undefined && match.startTime != '0'">The match
|
||||
started
|
||||
on
|
||||
{{match.startTime}}.</p>
|
||||
<p id="matchDuration" *ngIf="match.durationSeconds != undefined && match.durationSeconds != '0'">It lasted
|
||||
{{ (match.durationSeconds / 60).toFixed(2) }} minutes.</p>
|
||||
<p id="hero" *ngIf="match.heroes != 0">You played {{ match.heroes }} <img style="width: 2rem"*ngIf="match.heroes" src="assets/heroes/{{match.heroes}}.png">.</p>
|
||||
<p id="radiant" *ngIf="match.radiant == true; else elseBlock">You were Radiant <img style="width: 2rem" src="assets/Radiant_icon.png">.</p>
|
||||
<p>
|
||||
<ng-template #elseBlock>
|
||||
<p id="dire">You were Dire <img style="width: 2rem" src="assets/Dire_icon.png">.</p>
|
||||
</ng-template>
|
||||
</p>
|
||||
<p id="firstBloodTime">First blood was achieved at {{ (match.firstBloodTime / 60).toFixed(2) }}
|
||||
minutes.</p>
|
||||
<p id="matchVictory" *ngIf="match.victory == true; else elseBlock2">You won.</p>
|
||||
<p>
|
||||
<ng-template #elseBlock2>
|
||||
<p id="lost">You lost.</p>
|
||||
</ng-template>
|
||||
</p>
|
||||
<p id="goldLead" *ngIf="match.largestGoldLeadTeam != undefined && match.largestGoldLead != '0'">
|
||||
{{match.largestGoldLeadTeam}} had the highest gold
|
||||
lead of
|
||||
{{match.largestGoldLead}} gold.</p>
|
||||
<p id="xpLead" *ngIf="match.largestXpLeadTeam != undefined && match.largestXpLead != '0'">
|
||||
{{match.largestXpLeadTeam}} had the highest
|
||||
experience
|
||||
lead
|
||||
of {{match.largestXpLead}} experience.</p>
|
||||
<p id="deaths" *ngIf="match.deaths != undefined">You died {{match.deaths}} times.</p>
|
||||
<p id="feed" *ngIf="match.deaths > 10">You fed.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</ul>
|
||||
|
|
@ -0,0 +1,95 @@
|
|||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
import { NgbToast, NgbToastService, NgbToastType } from 'ngb-toast';
|
||||
import { Observable, of } from 'rxjs';
|
||||
import { AppModule } from 'src/app/app.module';
|
||||
import { Auth } from 'src/app/models/auth/auth.model';
|
||||
import { Match } from 'src/app/models/match/match.model';
|
||||
import { SPlayer } from 'src/app/models/s-player/splayer.model';
|
||||
import { Auth0Service } from 'src/app/services/auth0.service';
|
||||
import { SavePlayerService } from 'src/app/services/save-player.service';
|
||||
|
||||
import { UserProfileComponent } from './user-profile.component';
|
||||
|
||||
describe('UserProfileComponent', () => {
|
||||
let component: UserProfileComponent;
|
||||
let fixture: ComponentFixture<UserProfileComponent>;
|
||||
|
||||
let steamId = '66914827';
|
||||
|
||||
let player = new SPlayer();
|
||||
let auth = null;
|
||||
|
||||
let match = new Match();
|
||||
match.id = 1;
|
||||
match.authId = [1,2,3];
|
||||
match.durationSeconds = "1";
|
||||
match.victory = true;
|
||||
match.players = [{isVictory!: true, heroId!: 11}]
|
||||
match.firstBloodTime = "1";
|
||||
match.gameMode = "1";
|
||||
match.largestGoldLead = "1";
|
||||
match.largestGoldLeadTeam = "Dire";
|
||||
match.largestXpLead = "1";
|
||||
match.largestXpLeadTeam = "Radiant";
|
||||
match.startTime = "1";
|
||||
match.deaths = 11;
|
||||
match.radiant_gold_adv = [0, -34, 405, 224];
|
||||
match.radiant_xp_adv = [0, 24, 212, 211];
|
||||
match.heroes = "Outworld Destroyer";
|
||||
|
||||
player.name = "Ryon";
|
||||
player.id = 1;
|
||||
player.realName = "Real Ryon";
|
||||
player.avatar = "link";
|
||||
player.profileUri = "uri";
|
||||
player.matchesList = [match];
|
||||
|
||||
let user = {
|
||||
name: "Ryon",
|
||||
email: "ryon137@gmail.com",
|
||||
sub: 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'
|
||||
};
|
||||
|
||||
|
||||
|
||||
const savePlayerServiceSpy = jasmine.createSpyObj('SavePlayerService',[
|
||||
'getSavedPlayerById', 'getAuth', 'addAuth'
|
||||
]);
|
||||
const getSavedPlayerByIdSpy = savePlayerServiceSpy.getSavedPlayerById.and.returnValue(of(player));
|
||||
const getAuthSpy = savePlayerServiceSpy.getAuth.and.returnValue(of(auth));
|
||||
const addAuthSpy = savePlayerServiceSpy.addAuth.and.returnValue(of(auth));
|
||||
|
||||
const auth0Spy = jasmine.createSpyObj('Auth0Service',['getUser']);
|
||||
const getUserSpy = auth0Spy.getUser.and.returnValue(of(user));
|
||||
|
||||
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
declarations: [ UserProfileComponent ],
|
||||
providers: [
|
||||
{ provide: SavePlayerService, useValue: savePlayerServiceSpy },
|
||||
{ provide: Auth0Service, useValue: auth0Spy }
|
||||
],
|
||||
imports: [ AppModule ]
|
||||
})
|
||||
.compileComponents();
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(UserProfileComponent);
|
||||
component = fixture.componentInstance;
|
||||
component.steamId = steamId;
|
||||
component.windowReload = function() {};
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
fixture.destroy();
|
||||
});
|
||||
|
||||
it('if getAuth returns null, then player does not exist', ()=>{
|
||||
expect(component.playerExists).toBeFalse();
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
.matches:hover{
|
||||
cursor: pointer;
|
||||
}
|
||||
303
src/app/components/user-profile/user-profile.component.spec.ts
Normal file
|
|
@ -0,0 +1,303 @@
|
|||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
import { NgbToast, NgbToastService, NgbToastType } from 'ngb-toast';
|
||||
import { Observable, of } from 'rxjs';
|
||||
import { AppModule } from 'src/app/app.module';
|
||||
import { Auth } from 'src/app/models/auth/auth.model';
|
||||
import { Match } from 'src/app/models/match/match.model';
|
||||
import { SPlayer } from 'src/app/models/s-player/splayer.model';
|
||||
import { Auth0Service } from 'src/app/services/auth0.service';
|
||||
import { SavePlayerService } from 'src/app/services/save-player.service';
|
||||
|
||||
import { UserProfileComponent } from './user-profile.component';
|
||||
|
||||
describe('UserProfileComponent', () => {
|
||||
let component: UserProfileComponent;
|
||||
let fixture: ComponentFixture<UserProfileComponent>;
|
||||
|
||||
let steamId = '66914827';
|
||||
|
||||
let player = new SPlayer();
|
||||
let auth = new Auth();
|
||||
auth.steamId = '1';
|
||||
|
||||
let match = new Match();
|
||||
match.id = 1;
|
||||
match.authId = [1,2,3];
|
||||
match.durationSeconds = "1";
|
||||
match.victory = true;
|
||||
match.players = [{isVictory!: true, heroId!: 11}]
|
||||
match.firstBloodTime = "1";
|
||||
match.gameMode = "1";
|
||||
match.largestGoldLead = "1";
|
||||
match.largestGoldLeadTeam = "Dire";
|
||||
match.largestXpLead = "1";
|
||||
match.largestXpLeadTeam = "Radiant";
|
||||
match.startTime = "1";
|
||||
match.deaths = 11;
|
||||
match.radiant_gold_adv = [0, -34, 405, 224];
|
||||
match.radiant_xp_adv = [0, 24, 212, 211];
|
||||
match.heroes = "Outworld Destroyer";
|
||||
match.radiant = true;
|
||||
|
||||
player.name = "Ryon";
|
||||
player.id = 1;
|
||||
player.realName = "Real Ryon";
|
||||
player.avatar = "link";
|
||||
player.profileUri = "uri";
|
||||
player.matchesList = [match];
|
||||
|
||||
let user = {
|
||||
name: "Ryon",
|
||||
email: "ryon137@gmail.com",
|
||||
sub: 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'
|
||||
};
|
||||
|
||||
const savePlayerServiceSpy = jasmine.createSpyObj('SavePlayerService',[
|
||||
'getSavedPlayerById', 'getAuth', 'addAuth'
|
||||
]);
|
||||
const getSavedPlayerByIdSpy = savePlayerServiceSpy.getSavedPlayerById.and.returnValue(of(player));
|
||||
const getAuthSpy = savePlayerServiceSpy.getAuth.and.returnValue(of(auth));
|
||||
const addAuthSpy = savePlayerServiceSpy.addAuth.and.returnValue(of(auth));
|
||||
|
||||
|
||||
const auth0Spy = jasmine.createSpyObj('Auth0Service',['getUser']);
|
||||
const getUserSpy = auth0Spy.getUser.and.returnValue(of(user));
|
||||
|
||||
const toastSpy = jasmine.createSpyObj('NgbToastService',['remove','show']);
|
||||
const removeSpy = toastSpy.remove.and.returnValue(of(new NgbToast));
|
||||
const showSpy = toastSpy.show.and.returnValue(of(new NgbToast));
|
||||
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
declarations: [ UserProfileComponent ],
|
||||
providers: [
|
||||
{ provide: SavePlayerService, useValue: savePlayerServiceSpy },
|
||||
{ provide: Auth0Service, useValue: auth0Spy },
|
||||
{ provide: NgbToastService, useValue: toastSpy }
|
||||
],
|
||||
imports: [ AppModule ]
|
||||
})
|
||||
.compileComponents();
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(UserProfileComponent);
|
||||
component = fixture.componentInstance;
|
||||
component.steamId = steamId;
|
||||
component.windowReload = function() {};
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
fixture.destroy();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should display Enter your Steam ID if player does not exist', ()=>{
|
||||
component.playerExists = false;
|
||||
fixture.detectChanges();
|
||||
|
||||
const headerTag = fixture.debugElement.nativeElement.querySelector('#userDetails');
|
||||
expect(headerTag.textContent).toBe("Enter your Steam ID");
|
||||
});
|
||||
|
||||
it('should display submit button if player does not exist', ()=>{
|
||||
component.playerExists = false;
|
||||
fixture.detectChanges();
|
||||
|
||||
const headerTag = fixture.debugElement.nativeElement.querySelector('#submitButton');
|
||||
expect(headerTag.textContent).toBe("Submit");
|
||||
});
|
||||
|
||||
it('should display Account Information', ()=>{
|
||||
const headerTag = fixture.debugElement.nativeElement.querySelector('#userDetails');
|
||||
expect(headerTag.textContent).toBe("Account Information");
|
||||
});
|
||||
|
||||
it('should display User name', ()=>{
|
||||
const headerTag = fixture.debugElement.nativeElement.querySelector('#userName');
|
||||
expect(headerTag.textContent).toBe("User Name: " + user.name);
|
||||
});
|
||||
|
||||
it('should display User email', ()=>{
|
||||
const headerTag = fixture.debugElement.nativeElement.querySelector('#userEmail');
|
||||
expect(headerTag.textContent).toBe("User Email: " + user.email);
|
||||
});
|
||||
|
||||
it('should display User steam id', ()=>{
|
||||
component.playerId = '1';
|
||||
const headerTag = fixture.debugElement.nativeElement.querySelector('#playerId');
|
||||
expect(headerTag.textContent).toBe("Steam ID: " + component.playerId);
|
||||
});
|
||||
|
||||
it('should display player avatar if player exists', ()=>{
|
||||
component.playerExists = true;
|
||||
fixture.detectChanges();
|
||||
|
||||
const image = fixture.debugElement.nativeElement.querySelector('#image');
|
||||
expect(image['src']).toContain('https://steamcdn-a.akamaihd.net/steamcommunity/public/images/avatars/link');
|
||||
});
|
||||
|
||||
it('should display player name if player exists', ()=>{
|
||||
component.playerExists = true;
|
||||
fixture.detectChanges();
|
||||
|
||||
const htag = fixture.debugElement.nativeElement.querySelector('#playerName');
|
||||
expect(htag.textContent).toBe(player.name + "'s Saved Matches");
|
||||
});
|
||||
|
||||
it('should display match id if player exists', ()=>{
|
||||
component.playerExists = true;
|
||||
fixture.detectChanges();
|
||||
|
||||
const ptag = fixture.debugElement.nativeElement.querySelector('#matchId');
|
||||
expect(ptag.textContent).toBe("Match " + match.id);
|
||||
});
|
||||
|
||||
it('should display start time if player exists', ()=>{
|
||||
component.playerExists = true;
|
||||
component.isPlayer = true;
|
||||
fixture.detectChanges();
|
||||
|
||||
const ptag = fixture.debugElement.nativeElement.querySelector('#startTime');
|
||||
expect(ptag.textContent).toBe("The match started on " + match.startTime + ".");
|
||||
});
|
||||
|
||||
it('should display match duration if player exists', ()=>{
|
||||
component.playerExists = true;
|
||||
component.isPlayer = true;
|
||||
fixture.detectChanges();
|
||||
|
||||
const ptag = fixture.debugElement.nativeElement.querySelector('#matchDuration');
|
||||
expect(ptag.textContent).toBe("It lasted " + (match.durationSeconds / 60).toFixed(2) + " minutes.");
|
||||
});
|
||||
|
||||
it('should display hero if player exists', ()=>{
|
||||
component.playerExists = true;
|
||||
component.isPlayer = true;
|
||||
fixture.detectChanges();
|
||||
|
||||
const ptag = fixture.debugElement.nativeElement.querySelector('#hero');
|
||||
expect(ptag.textContent).toBe("You played " + match.heroes + " .");
|
||||
});
|
||||
|
||||
it('should display all match team side if radiant', ()=>{
|
||||
component.playerExists = true;
|
||||
component.isPlayer = true;
|
||||
fixture.detectChanges();
|
||||
|
||||
const pTag = fixture.debugElement.nativeElement.querySelector('#radiant');
|
||||
expect(pTag.textContent).toBe("You were Radiant .");
|
||||
});
|
||||
|
||||
it('should display all match team side if dire', ()=>{
|
||||
component.playerExists = true;
|
||||
component.isPlayer = true;
|
||||
match.radiant = false;
|
||||
fixture.detectChanges();
|
||||
|
||||
const pTag = fixture.debugElement.nativeElement.querySelector('#dire');
|
||||
expect(pTag.textContent).toBe("You were Dire .");
|
||||
});
|
||||
|
||||
it('should display first blood time if player exists', ()=>{
|
||||
component.playerExists = true;
|
||||
component.isPlayer = true;
|
||||
fixture.detectChanges();
|
||||
|
||||
const ptag = fixture.debugElement.nativeElement.querySelector('#firstBloodTime');
|
||||
expect(ptag.textContent).toBe("First blood was achieved at " + (match.firstBloodTime / 60).toFixed(2) + " minutes.");
|
||||
});
|
||||
|
||||
it('should display victory if player exists and player won', ()=>{
|
||||
component.playerExists = true;
|
||||
component.isPlayer = true;
|
||||
fixture.detectChanges();
|
||||
|
||||
const ptag = fixture.debugElement.nativeElement.querySelector('#matchVictory');
|
||||
expect(ptag.textContent).toBe("You won.");
|
||||
});
|
||||
|
||||
it('should display gold lead if player exists', ()=>{
|
||||
component.playerExists = true;
|
||||
component.isPlayer = true;
|
||||
fixture.detectChanges();
|
||||
|
||||
const ptag = fixture.debugElement.nativeElement.querySelector('#goldLead');
|
||||
expect(ptag.textContent).toBe(" " + match.largestGoldLeadTeam + " had the highest gold lead of " + match.largestGoldLead + " gold.");
|
||||
});
|
||||
|
||||
it('should display xp lead if player exists', ()=>{
|
||||
component.playerExists = true;
|
||||
component.isPlayer = true;
|
||||
fixture.detectChanges();
|
||||
|
||||
const ptag = fixture.debugElement.nativeElement.querySelector('#xpLead');
|
||||
expect(ptag.textContent).toBe(" " + match.largestXpLeadTeam + " had the highest experience lead of " + match.largestXpLead + " experience.");
|
||||
});
|
||||
|
||||
it('should display deaths if player exists', ()=>{
|
||||
component.playerExists = true;
|
||||
component.isPlayer = true;
|
||||
fixture.detectChanges();
|
||||
|
||||
const ptag = fixture.debugElement.nativeElement.querySelector('#deaths');
|
||||
expect(ptag.textContent).toBe("You died " + match.deaths + " times.");
|
||||
});
|
||||
|
||||
it('should display special message if player exists and player dies more than 10 times', ()=>{
|
||||
component.playerExists = true;
|
||||
component.isPlayer = true;
|
||||
fixture.detectChanges();
|
||||
|
||||
const ptag = fixture.debugElement.nativeElement.querySelector('#feed');
|
||||
expect(ptag.textContent).toBe("You fed.");
|
||||
});
|
||||
|
||||
it('removeToast should remove toast', ()=>{
|
||||
component.removeToast(new NgbToast);
|
||||
expect(removeSpy).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('if getUser returns data.sub, then authId should be populated', ()=>{
|
||||
expect(component.authId).toBe('aaaaaa');
|
||||
});
|
||||
|
||||
it('if getAuth is called, expect playerId to be truthy', ()=>{
|
||||
expect(component.playerId).toBeTruthy();
|
||||
});
|
||||
|
||||
it('if onClick is called, then isPlayer should be true', ()=>{
|
||||
component.onClick();
|
||||
expect(component.isPlayer).toBeTrue();
|
||||
});
|
||||
|
||||
it('if getSavedPlayerService is called, then player and matcheslist should exist', ()=>{
|
||||
expect(component.player).toBe(player);
|
||||
expect(component.player.matchesList).toBe(player.matchesList);
|
||||
});
|
||||
|
||||
it('if onSubmit is called and regex does not match, showFailure should be called', ()=>{
|
||||
component.onSubmit();
|
||||
component.steamId = " ";
|
||||
component.showFailure();
|
||||
expect(showSpy).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('if steamId is the larger format, number should be converted and showConversion should be called', ()=>{
|
||||
component.steamId = '76561198066745404';
|
||||
component.largeId = 99999999999n;
|
||||
component.conversionNum = 76561197960265728n;
|
||||
component.onSubmit();
|
||||
expect(showSpy).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('if onSubmit is called, addAuth should be called', ()=>{
|
||||
component.onSubmit();
|
||||
expect(addAuthSpy).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
138
src/app/components/user-profile/user-profile.component.ts
Normal file
|
|
@ -0,0 +1,138 @@
|
|||
import { Component, Input, OnInit } from '@angular/core';
|
||||
import { AuthService } from '@auth0/auth0-angular';
|
||||
import { NgbToast, NgbToastService, NgbToastType } from 'ngb-toast';
|
||||
import { Auth } from 'src/app/models/auth/auth.model';
|
||||
import { SPlayer } from 'src/app/models/s-player/splayer.model';
|
||||
import { Auth0Service } from 'src/app/services/auth0.service';
|
||||
import { SavePlayerService } from 'src/app/services/save-player.service';
|
||||
|
||||
@Component({
|
||||
selector: 'app-user-profile',
|
||||
templateUrl: './user-profile.component.html',
|
||||
styleUrls: ['./user-profile.component.scss']
|
||||
})
|
||||
export class UserProfileComponent implements OnInit {
|
||||
playerExists = true;
|
||||
auth = new Auth();
|
||||
playerId = '';
|
||||
isPlayer = false;
|
||||
player!: SPlayer;
|
||||
authId!: any;
|
||||
steamId = '';
|
||||
regex = /[0-9]{8}$/;
|
||||
largeId = 99999999999n;
|
||||
conversionNum = 76561197960265728n;
|
||||
data!: any;
|
||||
|
||||
constructor(private savePlayerService: SavePlayerService, public authentication: Auth0Service, private toastService: NgbToastService) {
|
||||
}
|
||||
ngOnInit(): void {
|
||||
//**********************************************************/
|
||||
// Fetch this user's ID and store it locally
|
||||
//**********************************************************/
|
||||
this.authentication.getUser().subscribe((data: any) => {
|
||||
if(data){
|
||||
this.data = data;
|
||||
}
|
||||
if(this.data.sub) {
|
||||
this.authId = this.data.sub.substring(14, 20);
|
||||
}
|
||||
//**********************************************************/
|
||||
// If user has not yet saved their ID, set flag to false
|
||||
//**********************************************************/
|
||||
this.savePlayerService.getAuth(this.authId).subscribe((object: any) => {
|
||||
if (object == null) {
|
||||
this.playerExists = false;
|
||||
}
|
||||
else {
|
||||
this.playerId = object.steamId;
|
||||
/**********************************************************/
|
||||
// Loop through matches, and display all of associated
|
||||
// player's match data
|
||||
//**********************************************************/
|
||||
this.savePlayerService.getSavedPlayerById(this.playerId).subscribe((player: SPlayer) => {
|
||||
this.player = player;
|
||||
this.player.matchesList.reverse();
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
onClick() {
|
||||
this.isPlayer = true;
|
||||
}
|
||||
|
||||
onClick2(){
|
||||
this.playerExists = false;
|
||||
}
|
||||
|
||||
onSubmit() {
|
||||
//**********************************************************/
|
||||
// Form validation
|
||||
//**********************************************************/
|
||||
if (!this.regex.test(this.steamId)) {
|
||||
this.showFailure();
|
||||
return;
|
||||
}
|
||||
//**********************************************************/
|
||||
// Convert steamId to proper format
|
||||
//**********************************************************/
|
||||
if (BigInt(this.steamId) > this.largeId) {
|
||||
this.steamId = (BigInt(this.steamId) - this.conversionNum).toString();
|
||||
this.steamId.slice(0, 7);
|
||||
this.showConversion();
|
||||
}
|
||||
//**********************************************************/
|
||||
// Set appropriate values, post them to database,
|
||||
// then reload page
|
||||
//**********************************************************/
|
||||
this.auth.steamId = this.steamId;
|
||||
this.auth.id = this.authId;
|
||||
this.savePlayerService.addAuth(this.auth);
|
||||
this.windowReload();
|
||||
}
|
||||
|
||||
//**********************************************************/
|
||||
// Toast for id conversion
|
||||
//**********************************************************/
|
||||
showConversion(): void {
|
||||
const toast: NgbToast = {
|
||||
toastType: NgbToastType.Info,
|
||||
text: "ID converted to correct format",
|
||||
dismissible: true,
|
||||
timeInSeconds: 5,
|
||||
onDismiss: () => {
|
||||
console.log("Toast dismissed!!");
|
||||
}
|
||||
}
|
||||
this.toastService.show(toast);
|
||||
}
|
||||
//**********************************************************/
|
||||
// Toast for id being too small
|
||||
//**********************************************************/
|
||||
showFailure(): void {
|
||||
const toast: NgbToast = {
|
||||
toastType: NgbToastType.Danger,
|
||||
text: "ID must be at least 8 digits",
|
||||
dismissible: true,
|
||||
timeInSeconds: 5,
|
||||
onDismiss: () => {
|
||||
console.log("Toast dismissed!!");
|
||||
}
|
||||
}
|
||||
this.toastService.show(toast);
|
||||
}
|
||||
//**********************************************************/
|
||||
// Remove toast
|
||||
//**********************************************************/
|
||||
removeToast(toast: NgbToast): void {
|
||||
this.toastService.remove(toast);
|
||||
}
|
||||
//**********************************************************/
|
||||
// Reload page
|
||||
//**********************************************************/
|
||||
windowReload(){
|
||||
location.reload();
|
||||
}
|
||||
}
|
||||
|
||||
4
src/app/models/auth/auth.model.ts
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
export class Auth {
|
||||
id!: any;
|
||||
steamId!: any;
|
||||
}
|
||||
4
src/app/models/hero/hero.model.ts
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
export class Hero {
|
||||
id!: any;
|
||||
displayName!: any;
|
||||
}
|
||||
23
src/app/models/match/match.model.ts
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
export class Match {
|
||||
id!: any;
|
||||
authId!: any[];
|
||||
durationSeconds!: any;
|
||||
victory!: any;
|
||||
firstBloodTime!: any;
|
||||
gameMode!: any;
|
||||
heroes!: any;
|
||||
largestGoldLead!: any;
|
||||
largestGoldLeadTeam!: any;
|
||||
largestXpLead!: any;
|
||||
largestXpLeadTeam!: any;
|
||||
startTime!: any;
|
||||
deaths!: any;
|
||||
radiant_gold_adv!: any;
|
||||
radiant_xp_adv!: any;
|
||||
first_blood_time!: any;
|
||||
start_time!: any;
|
||||
duration!: any;
|
||||
players!: any;
|
||||
radiant_win!: any;
|
||||
radiant: any;
|
||||
}
|
||||
10
src/app/models/s-player/splayer.model.ts
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
import { Match } from "../match/match.model";
|
||||
|
||||
export class SPlayer {
|
||||
name!: any;
|
||||
id!: any;
|
||||
realName!: any;
|
||||
avatar!: any;
|
||||
profileUri!: any;
|
||||
matchesList!: Match[];
|
||||
}
|
||||
35
src/app/services/auth0.service.spec.ts
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
import { ComponentFixture, ComponentFixtureAutoDetect, fakeAsync, TestBed, tick } from '@angular/core/testing';
|
||||
import { AuthService } from '@auth0/auth0-angular';
|
||||
import { of, throwError } from 'rxjs';
|
||||
|
||||
import { Auth0Service } from './auth0.service';
|
||||
|
||||
describe('Auth0Service', () => {
|
||||
let service: Auth0Service;
|
||||
|
||||
let user = {
|
||||
name: "Ryon",
|
||||
email: "ryon137@gmail.com"
|
||||
};
|
||||
|
||||
const authServiceSpy = jasmine.createSpyObj('Auth0Service', ['getUser']);
|
||||
const userSpy = authServiceSpy.getUser.and.returnValue(of(user));
|
||||
|
||||
beforeEach(() => {
|
||||
TestBed.configureTestingModule({
|
||||
providers: [
|
||||
{ provide: Auth0Service, useValue: authServiceSpy }
|
||||
]
|
||||
});
|
||||
service = TestBed.inject(Auth0Service);
|
||||
});
|
||||
|
||||
it('should be created', () => {
|
||||
expect(service).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should return an observable containing user authentication',()=>{
|
||||
service.getUser().subscribe();
|
||||
expect(userSpy.calls.any()).toBe(true);
|
||||
});
|
||||
});
|
||||
15
src/app/services/auth0.service.ts
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
import { Injectable } from '@angular/core';
|
||||
import { AuthService } from '@auth0/auth0-angular';
|
||||
import { Observable } from 'rxjs';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
})
|
||||
export class Auth0Service {
|
||||
|
||||
constructor(public authentication: AuthService) {}
|
||||
|
||||
getUser(): Observable<any>{
|
||||
return this.authentication.user$;
|
||||
}
|
||||
}
|
||||
48
src/app/services/opendota.service.spec.ts
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
import { TestBed } from '@angular/core/testing';
|
||||
import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing';
|
||||
|
||||
import { OpendotaService } from './opendota.service';
|
||||
import { SPlayer } from '../models/s-player/splayer.model';
|
||||
import { Match } from '../models/match/match.model';
|
||||
|
||||
describe('OpendotaService', () => {
|
||||
let httpTestingController: HttpTestingController;
|
||||
let service: OpendotaService;
|
||||
let baseUrl = 'https://api.opendota.com';
|
||||
let player = new SPlayer();
|
||||
let match = new Match();
|
||||
let apiKey = '368d3d7f-1034-483f-8226-e8e5de4f76b9';
|
||||
|
||||
const opendotaServiceSpy = jasmine.createSpyObj('OpendotaService', ['getPlayer', 'getMatch']);
|
||||
const getPlayerSpy = opendotaServiceSpy.getPlayer.and.returnValue(player);
|
||||
const getMatchSpy = opendotaServiceSpy.getMatch.and.returnValue(match);
|
||||
|
||||
beforeEach(() => {
|
||||
TestBed.configureTestingModule({
|
||||
imports: [HttpClientTestingModule]
|
||||
});
|
||||
httpTestingController = TestBed.get(HttpTestingController);
|
||||
service = TestBed.inject(OpendotaService);
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
httpTestingController.verify();
|
||||
})
|
||||
|
||||
it('should be created', () => {
|
||||
expect(service).toBeTruthy();
|
||||
});
|
||||
|
||||
it('getPlayer should make a GET call to the url', () => {
|
||||
service.getPlayer(1).subscribe();
|
||||
let req = httpTestingController.expectOne(baseUrl + "/api/players/1?api_key=" + apiKey);
|
||||
expect(req.request.method).toEqual("GET");
|
||||
});
|
||||
|
||||
it('getMatch should make a GET call to the url', () => {
|
||||
service.getMatch(1).subscribe();
|
||||
let req = httpTestingController.expectOne(baseUrl + "/api/matches/1?api_key=" + apiKey);
|
||||
expect(req.request.method).toEqual("GET");
|
||||
});
|
||||
|
||||
});
|
||||
25
src/app/services/opendota.service.ts
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
import { HttpClient } from '@angular/common/http';
|
||||
import { Injectable } from '@angular/core';
|
||||
import { Observable } from 'rxjs';
|
||||
import { SPlayer } from '../models/s-player/splayer.model';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
})
|
||||
//**********************************************************/
|
||||
// Connects to Open Dota API to retrieve data
|
||||
//**********************************************************/
|
||||
export class OpendotaService {
|
||||
|
||||
endpoint: string = `https://api.opendota.com`;
|
||||
apiKey = '368d3d7f-1034-483f-8226-e8e5de4f76b9';
|
||||
|
||||
constructor(private http: HttpClient) { }
|
||||
|
||||
getPlayer(id: any): Observable<SPlayer>{
|
||||
return this.http.get<any>(`${this.endpoint}/api/players/${id}?api_key=${this.apiKey}`);
|
||||
}
|
||||
getMatch(id: any): Observable<any>{
|
||||
return this.http.get<any>(`${this.endpoint}/api/matches/${id}?api_key=${this.apiKey}`);
|
||||
}
|
||||
}
|
||||
147
src/app/services/save-player.service.spec.ts
Normal file
|
|
@ -0,0 +1,147 @@
|
|||
import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing';
|
||||
import { ComponentFixtureAutoDetect, TestBed } from '@angular/core/testing';
|
||||
import { NgbToast, NgbToastService } from 'ngb-toast';
|
||||
import { of } from 'rxjs';
|
||||
import { Auth } from '../models/auth/auth.model';
|
||||
import { Match } from '../models/match/match.model';
|
||||
import { SPlayer } from '../models/s-player/splayer.model';
|
||||
|
||||
import { SavePlayerService } from './save-player.service';
|
||||
|
||||
describe('SavePlayerService', () => {
|
||||
let httpTestingController: HttpTestingController;
|
||||
let service: SavePlayerService;
|
||||
let player = new SPlayer();
|
||||
let match = new Match();
|
||||
let auth = new Auth();
|
||||
let baseUrl = 'https://ryon.ee-cognizantacademy.com'
|
||||
|
||||
const toastServiceSpy = jasmine.createSpyObj('toastService', ['pop','remove', 'show']);
|
||||
const removeSpy = toastServiceSpy.remove.and.returnValue(of(new NgbToast));
|
||||
const showSpy = toastServiceSpy.show.and.returnValue(of(new NgbToast));
|
||||
|
||||
beforeEach(() => {
|
||||
TestBed.configureTestingModule({
|
||||
imports: [HttpClientTestingModule],
|
||||
providers: [
|
||||
{ provide: NgbToastService, useValue: toastServiceSpy}
|
||||
]
|
||||
});
|
||||
httpTestingController = TestBed.get(HttpTestingController);
|
||||
service = TestBed.inject(SavePlayerService);
|
||||
});
|
||||
|
||||
afterEach(()=>{
|
||||
httpTestingController.verify();
|
||||
})
|
||||
|
||||
it('should be created', () => {
|
||||
expect(service).toBeTruthy();
|
||||
});
|
||||
|
||||
it('addPlayer should make a POST call to the url', ()=>{
|
||||
let didAdd = service.addPlayer(player);
|
||||
let req = httpTestingController.expectOne(baseUrl+"/player");
|
||||
expect(req.request.method).toEqual("POST");
|
||||
expect(didAdd).toBe(true);
|
||||
});
|
||||
|
||||
it('updatePlayer should make a PUT call to the url', ()=>{
|
||||
let didAdd = service.updatePlayer(player);
|
||||
let req = httpTestingController.expectOne(baseUrl+"/player");
|
||||
expect(req.request.method).toEqual("PUT");
|
||||
expect(didAdd).toBe(true);
|
||||
});
|
||||
|
||||
it('deletePlayer should make a DELETE call to the url', ()=>{
|
||||
let didAdd = service.deletePlayer(player);
|
||||
let req = httpTestingController.expectOne(baseUrl+"/player/");
|
||||
expect(req.request.method).toEqual("DELETE");
|
||||
expect(didAdd).toBe(true);
|
||||
});
|
||||
|
||||
it('addMatch should make a POST call to the url', ()=>{
|
||||
let didAdd = service.addMatch(match,player);
|
||||
let req = httpTestingController.expectOne(baseUrl+"/match");
|
||||
expect(req.request.method).toEqual("POST");
|
||||
expect(didAdd).toBe(true);
|
||||
});
|
||||
|
||||
it('updateMatch should make a PUT call to the url', ()=>{
|
||||
let didAdd = service.updateMatch(match,player);
|
||||
let req = httpTestingController.expectOne(baseUrl+"/match");
|
||||
expect(req.request.method).toEqual("PUT");
|
||||
expect(didAdd).toBe(true);
|
||||
});
|
||||
|
||||
it('deleteMatch should make a DELETE call to the url', ()=>{
|
||||
let didAdd = service.deleteMatch(match);
|
||||
let req = httpTestingController.expectOne(baseUrl+"/match/");
|
||||
expect(req.request.method).toEqual("DELETE");
|
||||
expect(didAdd).toBe(true);
|
||||
});
|
||||
|
||||
it('getAllSavedPlayers should make a GET call to the url', ()=>{
|
||||
service.getAllSavedPlayers().subscribe();
|
||||
let req = httpTestingController.expectOne(baseUrl+"/players");
|
||||
expect(req.request.method).toEqual("GET");
|
||||
});
|
||||
|
||||
it('getSavedPlayerById should make a GET call to the url', ()=>{
|
||||
service.getSavedPlayerById(1).subscribe();
|
||||
let req = httpTestingController.expectOne(baseUrl+"/player/id/1");
|
||||
expect(req.request.method).toEqual("GET");
|
||||
});
|
||||
|
||||
it('getSavedPlayerByName should make a GET call to the url', ()=>{
|
||||
service.getSavedPlayerByName("Ryon").subscribe();
|
||||
let req = httpTestingController.expectOne(baseUrl+"/player/name/Ryon");
|
||||
expect(req.request.method).toEqual("GET");
|
||||
});
|
||||
|
||||
it('getSavedMatch should make a GET call to the url', ()=>{
|
||||
service.getSavedMatch(1).subscribe();
|
||||
let req = httpTestingController.expectOne(baseUrl+"/match/id/1");
|
||||
expect(req.request.method).toEqual("GET");
|
||||
});
|
||||
|
||||
it('getAllSavedMatches should make a GET call to the url', ()=>{
|
||||
service.getAllSavedMatches().subscribe();
|
||||
let req = httpTestingController.expectOne(baseUrl+"/matches");
|
||||
expect(req.request.method).toEqual("GET");
|
||||
});
|
||||
|
||||
it('addAuth should make a POST call to the url', ()=>{
|
||||
let didAdd = service.addAuth(auth);
|
||||
let req = httpTestingController.expectOne(baseUrl+"/auth");
|
||||
expect(req.request.method).toEqual("POST");
|
||||
expect(didAdd).toBe(true);
|
||||
});
|
||||
|
||||
it('getAuth should make a GET call to the url', ()=>{
|
||||
service.getAuth(1).subscribe();
|
||||
let req = httpTestingController.expectOne(baseUrl+"/auth/id/1");
|
||||
expect(req.request.method).toEqual("GET");
|
||||
});
|
||||
|
||||
it('showMatchAddSuccess should execute toast show', ()=>{
|
||||
service.showMatchAddSuccess();
|
||||
expect(showSpy).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('showPlayerAddSuccess should execute toast show', ()=>{
|
||||
service.showPlayerAddSuccess();
|
||||
expect(showSpy).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('showFailure should execute toast show', ()=>{
|
||||
service.showFailure();
|
||||
expect(showSpy).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('removeToast should execute toast remove', ()=>{
|
||||
service.removeToast(new NgbToast);
|
||||
expect(removeSpy).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
});
|
||||
166
src/app/services/save-player.service.ts
Normal file
|
|
@ -0,0 +1,166 @@
|
|||
import { HttpClient, HttpHeaders } from '@angular/common/http';
|
||||
import { Injectable } from '@angular/core';
|
||||
import { Observable } from 'rxjs';
|
||||
import { Match } from '../models/match/match.model';
|
||||
import { SPlayer } from '../models/s-player/splayer.model';
|
||||
|
||||
import { NgbToast, NgbToastService, NgbToastType } from 'ngb-toast';
|
||||
import { Auth } from '../models/auth/auth.model';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
})
|
||||
export class SavePlayerService {
|
||||
|
||||
//endpoint: string = 'https://ryon.ee-cognizantacademy.com';
|
||||
//endpoint: string = 'http://ryonbackend-env.eba-pbjsc7zw.us-east-2.elasticbeanstalk.com';
|
||||
//endpoint: string = 'http://localhost:8000';
|
||||
//endpoint: string = 'http://localhost:3306';
|
||||
endpoint: string = 'http://protractorbackend-env.eba-3jtcbg8v.us-east-2.elasticbeanstalk.com';
|
||||
|
||||
postHeader = {
|
||||
headers: new HttpHeaders({
|
||||
'Content-Type': 'application/json'
|
||||
})
|
||||
};
|
||||
|
||||
constructor(private http: HttpClient, private toastService: NgbToastService) { }
|
||||
addAuth(auth: Auth): boolean{
|
||||
this.http.post<Auth>(this.endpoint+"/auth", auth,
|
||||
this.postHeader).subscribe(res => {
|
||||
}, (err) => {
|
||||
console.log(err);
|
||||
this.showFailure();
|
||||
});
|
||||
this.showPlayerAddSuccess();
|
||||
return true;
|
||||
}
|
||||
|
||||
addPlayer(player: SPlayer): boolean{
|
||||
this.http.post<SPlayer>(this.endpoint+"/player", player,
|
||||
this.postHeader).subscribe(res => {
|
||||
}, (err) => {
|
||||
console.log(err);
|
||||
this.showFailure();
|
||||
});
|
||||
this.showPlayerAddSuccess();
|
||||
return true;
|
||||
}
|
||||
|
||||
updatePlayer(player: SPlayer): boolean{
|
||||
this.http.put<SPlayer>(this.endpoint+"/player", player,
|
||||
this.postHeader).subscribe(res => {
|
||||
}, (err) => {
|
||||
console.log(err);
|
||||
this.showFailure();
|
||||
});
|
||||
return true;
|
||||
}
|
||||
|
||||
deletePlayer(player: SPlayer): boolean{
|
||||
this.http.delete<SPlayer>(this.endpoint+"/player/", player.id)
|
||||
.subscribe(res => {
|
||||
}, (err) => {
|
||||
console.log(err);
|
||||
this.showFailure();
|
||||
});
|
||||
return true;
|
||||
}
|
||||
|
||||
addMatch(match: Match, player: SPlayer): boolean{
|
||||
this.http.post<Match>(this.endpoint+"/match", match,
|
||||
this.postHeader).subscribe(res => {this.addPlayer(player)
|
||||
}, (err) => {
|
||||
console.log(err);
|
||||
this.showFailure();
|
||||
});
|
||||
this.showMatchAddSuccess();
|
||||
return true;
|
||||
}
|
||||
|
||||
updateMatch(match: Match, player: SPlayer): boolean{
|
||||
this.http.put<Match>(this.endpoint+"/match", match,
|
||||
this.postHeader).subscribe(res => {this.updatePlayer(player)
|
||||
}, (err) => {
|
||||
console.log(err);
|
||||
this.showFailure();
|
||||
});
|
||||
return true;
|
||||
}
|
||||
|
||||
deleteMatch(match: Match): boolean{
|
||||
this.http.delete<Match>(this.endpoint+"/match/", match.id)
|
||||
.subscribe(res => {
|
||||
}, (err) => {
|
||||
console.log(err);
|
||||
this.showFailure();
|
||||
});
|
||||
return true;
|
||||
}
|
||||
|
||||
getAuth(id: any): Observable<Auth>{
|
||||
return this.http.get<any>(`${this.endpoint}/auth/id/${id}`);
|
||||
}
|
||||
|
||||
getAllSavedPlayers(): Observable<SPlayer>{
|
||||
return this.http.get<any>(`${this.endpoint}/players`);
|
||||
}
|
||||
|
||||
getSavedPlayerById(id: any): Observable<SPlayer>{
|
||||
return this.http.get<any>(`${this.endpoint}/player/id/${id}`);
|
||||
}
|
||||
getSavedPlayerByName(name: any): Observable<SPlayer>{
|
||||
return this.http.get<any>(`${this.endpoint}/player/name/${name}`);
|
||||
}
|
||||
|
||||
getSavedMatch(id:any): Observable<Match>{
|
||||
return this.http.get<any>(`${this.endpoint}/match/id/${id}`);
|
||||
}
|
||||
|
||||
getAllSavedMatches(): Observable<Match>{
|
||||
return this.http.get<any>(`${this.endpoint}/matches`);
|
||||
}
|
||||
|
||||
showMatchAddSuccess(): void {
|
||||
const toast: NgbToast = {
|
||||
toastType: NgbToastType.Success,
|
||||
text: "Match added successfullly",
|
||||
dismissible: true,
|
||||
timeInSeconds: 5,
|
||||
onDismiss: () => {
|
||||
console.log("Toast dismissed!!");
|
||||
}
|
||||
}
|
||||
this.toastService.show(toast);
|
||||
}
|
||||
showPlayerAddSuccess(): void {
|
||||
const toast: NgbToast = {
|
||||
toastType: NgbToastType.Success,
|
||||
text: "Player added successfullly",
|
||||
dismissible: true,
|
||||
timeInSeconds: 5,
|
||||
onDismiss: () => {
|
||||
console.log("Toast dismissed!!");
|
||||
}
|
||||
}
|
||||
this.toastService.show(toast);
|
||||
}
|
||||
|
||||
showFailure(): void {
|
||||
const toast: NgbToast = {
|
||||
toastType: NgbToastType.Danger,
|
||||
text: "Failure",
|
||||
dismissible: true,
|
||||
timeInSeconds: 5,
|
||||
onDismiss: () => {
|
||||
console.log("Toast dismissed!!");
|
||||
}
|
||||
}
|
||||
this.toastService.show(toast);
|
||||
}
|
||||
|
||||
removeToast(toast: NgbToast): void {
|
||||
this.toastService.remove(toast);
|
||||
}
|
||||
|
||||
}
|
||||
67
src/app/services/stratz.service.spec.ts
Normal file
|
|
@ -0,0 +1,67 @@
|
|||
import { TestBed } from '@angular/core/testing';
|
||||
import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing';
|
||||
|
||||
import { StratzService } from './stratz.service';
|
||||
import { SPlayer } from '../models/s-player/splayer.model';
|
||||
import { Hero } from '../models/hero/hero.model';
|
||||
import { Match } from '../models/match/match.model';
|
||||
|
||||
describe('StratzService', () => {
|
||||
let httpTestingController: HttpTestingController;
|
||||
let service: StratzService;
|
||||
let baseUrl = `https://api.stratz.com`;
|
||||
let player = new SPlayer();
|
||||
let hero = new Hero();
|
||||
let match = new Match();
|
||||
|
||||
|
||||
|
||||
const stratzServiceSpy = jasmine.createSpyObj('StratzService',['getPlayer','getPlayerMatches','getHero','getMatch']);
|
||||
const getPlayerSpy = stratzServiceSpy.getPlayer.and.returnValue(player);
|
||||
const getPlayerMatchesSpy = stratzServiceSpy.getPlayerMatches.and.returnValue(match);
|
||||
const getHeroSpy = stratzServiceSpy.getHero.and.returnValue(hero);
|
||||
const getMatchSpy = stratzServiceSpy.getMatch.and.returnValue(match);
|
||||
|
||||
|
||||
beforeEach(() => {
|
||||
TestBed.configureTestingModule({
|
||||
imports: [ HttpClientTestingModule ]
|
||||
});
|
||||
httpTestingController = TestBed.get(HttpTestingController);
|
||||
service = TestBed.inject(StratzService);
|
||||
});
|
||||
|
||||
afterEach(()=>{
|
||||
httpTestingController.verify();
|
||||
})
|
||||
|
||||
it('should be created', () => {
|
||||
expect(service).toBeTruthy();
|
||||
});
|
||||
|
||||
it('getPlayer should make a GET call to the url', ()=> {
|
||||
service.getPlayer(1).subscribe();
|
||||
let req = httpTestingController.expectOne(baseUrl+"/api/v1/Player/1");
|
||||
expect(req.request.method).toEqual("GET");
|
||||
});
|
||||
|
||||
it('getPlayerMatches should make a GET call to the url', ()=> {
|
||||
service.getPlayerMatches(1).subscribe();
|
||||
let req = httpTestingController.expectOne(baseUrl+"/api/v1/Player/1/matches");
|
||||
expect(req.request.method).toEqual("GET");
|
||||
});
|
||||
|
||||
it('getHero should make a GET call to the url', ()=> {
|
||||
service.getHero().subscribe();
|
||||
let req = httpTestingController.expectOne(baseUrl+"/api/v1/Hero");
|
||||
expect(req.request.method).toEqual("GET");
|
||||
});
|
||||
|
||||
it('getMatch should make a GET call to the url', ()=> {
|
||||
service.getMatch(1).subscribe();
|
||||
let req = httpTestingController.expectOne(baseUrl+"/api/v1/Match/1");
|
||||
expect(req.request.method).toEqual("GET");
|
||||
});
|
||||
|
||||
|
||||
});
|
||||
41
src/app/services/stratz.service.ts
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
import { HttpClient, HttpHeaders } from '@angular/common/http';
|
||||
import { Injectable } from '@angular/core';
|
||||
import { Observable } from 'rxjs';
|
||||
import { Match } from '../models/match/match.model';
|
||||
import { SPlayer } from '../models/s-player/splayer.model';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
})
|
||||
//**********************************************************/
|
||||
// Connects to Stratz API to retrieve data
|
||||
//**********************************************************/
|
||||
export class StratzService {
|
||||
|
||||
endpoint: string = `https://api.stratz.com`;
|
||||
|
||||
token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJuYW1laWQiOiJodHRwczovL3N0ZWFtY29tbXVuaXR5LmNvbS9vcGVuaWQvaWQvNzY1NjExOTgwNjY3NDU0MDQiLCJ1bmlxdWVfbmFtZSI6Ikl0J3MgTm8gVXNlIiwiU3ViamVjdCI6ImRmY2Y3NDg2LWNhNWUtNGFmMi04ZTgwLTM3MzU2MzQ5YTc5MSIsIlN0ZWFtSWQiOiIxMDY0Nzk2NzYiLCJuYmYiOjE2Mzc1OTg4NTMsImV4cCI6MTY2OTEzNDg1MywiaWF0IjoxNjM3NTk4ODUzLCJpc3MiOiJodHRwczovL2FwaS5zdHJhdHouY29tIn0.d3RSfgc4D1y-NCY19j7xaxkE_c7ExfRkvqLEYJm4VA0";
|
||||
|
||||
header = {
|
||||
headers: new HttpHeaders({
|
||||
'Authorization' : `Bearer ${this.token}`})
|
||||
};
|
||||
|
||||
constructor(private http: HttpClient) {
|
||||
|
||||
}
|
||||
|
||||
|
||||
getPlayer(id: any): Observable<SPlayer> {
|
||||
return this.http.get<any>(`${this.endpoint}/api/v1/Player/${id}`, this.header);
|
||||
}
|
||||
getPlayerMatches(id:any): Observable<Match> {
|
||||
return this.http.get<any>(`${this.endpoint}/api/v1/Player/${id}/matches`, this.header);
|
||||
}
|
||||
getHero(): Observable<any>{
|
||||
return this.http.get<any>(`${this.endpoint}/api/v1/Hero`, this.header);
|
||||
}
|
||||
getMatch(id:any): Observable<any>{
|
||||
return this.http.get<any>(`${this.endpoint}/api/v1/Match/${id}`, this.header);
|
||||
}
|
||||
}
|
||||
0
src/assets/.gitkeep
Normal file
BIN
src/assets/Dire_icon.png
Normal file
|
After Width: | Height: | Size: 23 KiB |
BIN
src/assets/Radiant_icon.png
Normal file
|
After Width: | Height: | Size: 27 KiB |
BIN
src/assets/heroes/Abaddon.png
Normal file
|
After Width: | Height: | Size: 1.2 KiB |
BIN
src/assets/heroes/Alchemist.png
Normal file
|
After Width: | Height: | Size: 1.4 KiB |
BIN
src/assets/heroes/Ancient Apparition.png
Normal file
|
After Width: | Height: | Size: 1.8 KiB |
BIN
src/assets/heroes/Anti-Mage.png
Normal file
|
After Width: | Height: | Size: 1.6 KiB |
BIN
src/assets/heroes/Arc Warden.png
Normal file
|
After Width: | Height: | Size: 2.2 KiB |
BIN
src/assets/heroes/Axe.png
Normal file
|
After Width: | Height: | Size: 855 B |
BIN
src/assets/heroes/Bane.png
Normal file
|
After Width: | Height: | Size: 1.4 KiB |
BIN
src/assets/heroes/Batrider.png
Normal file
|
After Width: | Height: | Size: 900 B |
BIN
src/assets/heroes/Beastmaster.png
Normal file
|
After Width: | Height: | Size: 1.6 KiB |
BIN
src/assets/heroes/Bloodseeker.png
Normal file
|
After Width: | Height: | Size: 1.2 KiB |
BIN
src/assets/heroes/Bounty Hunter.png
Normal file
|
After Width: | Height: | Size: 1.5 KiB |
BIN
src/assets/heroes/Brewmaster.png
Normal file
|
After Width: | Height: | Size: 2.3 KiB |
BIN
src/assets/heroes/Bristleback.png
Normal file
|
After Width: | Height: | Size: 1.9 KiB |
BIN
src/assets/heroes/Broodmother.png
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
src/assets/heroes/Centaur Warrunner.png
Normal file
|
After Width: | Height: | Size: 1.9 KiB |
BIN
src/assets/heroes/Chaos Knight.png
Normal file
|
After Width: | Height: | Size: 1.6 KiB |
BIN
src/assets/heroes/Chen.png
Normal file
|
After Width: | Height: | Size: 1.6 KiB |
BIN
src/assets/heroes/Clinkz.png
Normal file
|
After Width: | Height: | Size: 1.5 KiB |
BIN
src/assets/heroes/Clockwerk.png
Normal file
|
After Width: | Height: | Size: 1.4 KiB |
BIN
src/assets/heroes/Crystal Maiden.png
Normal file
|
After Width: | Height: | Size: 2.5 KiB |
BIN
src/assets/heroes/Dark Seer.png
Normal file
|
After Width: | Height: | Size: 1.2 KiB |
BIN
src/assets/heroes/Dazzle.png
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
src/assets/heroes/Death Prophet.png
Normal file
|
After Width: | Height: | Size: 1.6 KiB |
BIN
src/assets/heroes/Disruptor.png
Normal file
|
After Width: | Height: | Size: 1.7 KiB |
BIN
src/assets/heroes/Doom.png
Normal file
|
After Width: | Height: | Size: 1.6 KiB |
BIN
src/assets/heroes/Dragon Knight.png
Normal file
|
After Width: | Height: | Size: 1.5 KiB |
BIN
src/assets/heroes/Drow Ranger.png
Normal file
|
After Width: | Height: | Size: 1.6 KiB |
BIN
src/assets/heroes/Earth Spirit.png
Normal file
|
After Width: | Height: | Size: 2.1 KiB |
BIN
src/assets/heroes/Earthshaker.png
Normal file
|
After Width: | Height: | Size: 1.2 KiB |
BIN
src/assets/heroes/Elder Titan.png
Normal file
|
After Width: | Height: | Size: 1.8 KiB |
BIN
src/assets/heroes/Ember Spirit.png
Normal file
|
After Width: | Height: | Size: 1.3 KiB |
BIN
src/assets/heroes/Enchantress.png
Normal file
|
After Width: | Height: | Size: 1.9 KiB |
BIN
src/assets/heroes/Enigma.png
Normal file
|
After Width: | Height: | Size: 1 KiB |
BIN
src/assets/heroes/Faceless Void.png
Normal file
|
After Width: | Height: | Size: 1.4 KiB |
BIN
src/assets/heroes/Grimstroke.png
Normal file
|
After Width: | Height: | Size: 964 B |
BIN
src/assets/heroes/Gyrocopter.png
Normal file
|
After Width: | Height: | Size: 1.4 KiB |
BIN
src/assets/heroes/Huskar.png
Normal file
|
After Width: | Height: | Size: 1.4 KiB |
BIN
src/assets/heroes/Invoker.png
Normal file
|
After Width: | Height: | Size: 2.4 KiB |
BIN
src/assets/heroes/Io.png
Normal file
|
After Width: | Height: | Size: 2.9 KiB |
BIN
src/assets/heroes/Jakiro.png
Normal file
|
After Width: | Height: | Size: 1.5 KiB |
BIN
src/assets/heroes/Juggernaut.png
Normal file
|
After Width: | Height: | Size: 833 B |
BIN
src/assets/heroes/Keeper of the Light.png
Normal file
|
After Width: | Height: | Size: 1.5 KiB |
BIN
src/assets/heroes/Kunkka.png
Normal file
|
After Width: | Height: | Size: 1.5 KiB |
BIN
src/assets/heroes/Legion Commander.png
Normal file
|
After Width: | Height: | Size: 2.4 KiB |