Transfering from old repo

This commit is contained in:
ryoncook 2022-01-14 10:58:24 -06:00
commit 4bb95ca2a5
181 changed files with 16122 additions and 0 deletions

17
.browserslistrc Normal file
View 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
View 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
View 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
View 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
View 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
View 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
View 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

File diff suppressed because it is too large Load diff

49
package.json Normal file
View 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"
}
}

View 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 { }

View 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>

View file

View 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
View 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
View 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 { }

View file

@ -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>

View file

@ -0,0 +1,5 @@
.linkFix{
text-decoration: none;
color: white;
margin-right: 1rem;
}

View 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();
});
});

View 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) {
}
}

View 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>

View 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();
});
});

View 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 {
}
}

View 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>

View 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%;
}

View 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");
})
});

View 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 {
}
}

View 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>

View file

@ -0,0 +1,3 @@
.matches:hover{
cursor: pointer;
}

View 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.");
});
});

View 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;
}
}

View 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>

View file

@ -0,0 +1,14 @@
h3{
padding-bottom: 1rem;
}
h1{
padding-bottom: 1rem;
}
p{
font-size: 18px;
}
button{
//margin-left: 1rem;
margin-top: .25rem;
}

View 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();
});
});

View 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();
});
});

View 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
//

View 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>

View file

@ -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();
});
});

View file

@ -0,0 +1,3 @@
.matches:hover{
cursor: pointer;
}

View 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();
});
});

View 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();
}
}

View file

@ -0,0 +1,4 @@
export class Auth {
id!: any;
steamId!: any;
}

View file

@ -0,0 +1,4 @@
export class Hero {
id!: any;
displayName!: any;
}

View 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;
}

View 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[];
}

View 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);
});
});

View 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$;
}
}

View 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");
});
});

View 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}`);
}
}

View 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();
});
});

View 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);
}
}

View 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");
});
});

View 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
View file

BIN
src/assets/Dire_icon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

BIN
src/assets/Radiant_icon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

BIN
src/assets/heroes/Axe.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 855 B

BIN
src/assets/heroes/Bane.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 900 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

BIN
src/assets/heroes/Chen.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

BIN
src/assets/heroes/Doom.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 964 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

BIN
src/assets/heroes/Io.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 833 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Some files were not shown because too many files have changed in this diff Show more