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