Compare commits

..

No commits in common. "master" and "CHAL-1" have entirely different histories.

75 changed files with 1 additions and 9685 deletions

33
Jenkinsfile vendored
View File

@ -1,33 +0,0 @@
pipeline {
agent {
docker { image 'elixir:1.9.4' }
}
stages {
stage('Build') {
steps {
sh "elixir -v"
dir("challange_accepted") {
sh "mix compile && MIX_ENV=test mix compile"
}
}
}
stage('Test') {
steps {
dir("challange_accepted") {
sh "mix test"
}
}
}
stage('Build release') {
steps {
dir("challange_accepted") {
sh "mix release"
}
}
}
}
}

View File

@ -1,2 +1 @@
<h1> ChallangeAccepted </h1>
Projekt
<h1> ChallangeAccepted </h1>

View File

@ -1,4 +0,0 @@
# Used by "mix format"
[
inputs: ["{mix,.formatter}.exs", "{config,lib,test}/**/*.{ex,exs}"]
]

View File

@ -1,24 +0,0 @@
# The directory Mix will write compiled artifacts to.
/_build/
# If you run "mix test --cover", coverage assets end up here.
/cover/
# The directory Mix downloads your dependencies sources to.
/deps/
# Where third-party dependencies like ExDoc output generated docs.
/doc/
# Ignore .fetch files in case you like to edit your project deps locally.
/.fetch
# If the VM crashes, it generates a dump, let's ignore it too.
erl_crash.dump
# Also ignore archive artifacts (built via "mix archive.build").
*.ez
# Ignore package tarball (built via "mix hex.build").
challange_accepted-*.tar

View File

@ -1,21 +0,0 @@
# ChallangeAccepted
**TODO: Add description**
## Installation
If [available in Hex](https://hex.pm/docs/publish), the package can be installed
by adding `challange_accepted` to your list of dependencies in `mix.exs`:
```elixir
def deps do
[
{:challange_accepted, "~> 0.1.0"}
]
end
```
Documentation can be generated with [ExDoc](https://github.com/elixir-lang/ex_doc)
and published on [HexDocs](https://hexdocs.pm). Once published, the docs can
be found at [https://hexdocs.pm/challange_accepted](https://hexdocs.pm/challange_accepted).

View File

@ -1,18 +0,0 @@
defmodule ChallangeAccepted do
@moduledoc """
Documentation for ChallangeAccepted.
"""
@doc """
Hello world.
## Examples
iex> ChallangeAccepted.hello()
:world
"""
def hello do
:world
end
end

View File

@ -1,28 +0,0 @@
defmodule ChallangeAccepted.MixProject do
use Mix.Project
def project do
[
app: :challange_accepted,
version: "0.1.0",
elixir: "~> 1.9",
start_permanent: Mix.env() == :prod,
deps: deps()
]
end
# Run "mix help compile.app" to learn about applications.
def application do
[
extra_applications: [:logger]
]
end
# Run "mix help deps" to learn about dependencies.
defp deps do
[
# {:dep_from_hexpm, "~> 0.3.0"},
# {:dep_from_git, git: "https://github.com/elixir-lang/my_dep.git", tag: "0.1.0"}
]
end
end

View File

@ -1,8 +0,0 @@
defmodule ChallangeAcceptedTest do
use ExUnit.Case
doctest ChallangeAccepted
test "greets the world" do
assert ChallangeAccepted.hello() == :world
end
end

View File

@ -1 +0,0 @@
ExUnit.start()

View File

@ -1,13 +0,0 @@
# 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
[*.md]
max_line_length = off
trim_trailing_whitespace = false

46
front/.gitignore vendored
View File

@ -1,46 +0,0 @@
# 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
speed-measure-plugin*.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

7934
front/package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -1,40 +0,0 @@
{
"name": "angular-8-registration-login-example",
"version": "1.0.0",
"repository": {
"type": "git",
"url": "https://github.com/cornflourblue/angular-8-registration-login-example.git"
},
"scripts": {
"build": "webpack --mode production",
"start": "webpack-dev-server --mode development --open"
},
"license": "MIT",
"dependencies": {
"@angular/common": "^8.0.0",
"@angular/compiler": "^8.0.0",
"@angular/core": "^8.0.0",
"@angular/forms": "^8.0.0",
"@angular/platform-browser": "^8.0.0",
"@angular/platform-browser-dynamic": "^8.0.0",
"@angular/router": "^8.0.0",
"core-js": "^3.1.3",
"rxjs": "^6.3.3",
"zone.js": "^0.9.1"
},
"devDependencies": {
"@types/node": "^12.0.7",
"angular2-template-loader": "^0.6.2",
"css-loader": "^2.1.1",
"html-loader": "^0.5.5",
"html-webpack-plugin": "^3.2.0",
"less": "^3.0.4",
"less-loader": "^5.0.0",
"style-loader": "^0.23.1",
"ts-loader": "^6.0.1",
"typescript": "^3.1.3",
"webpack": "^4.32.2",
"webpack-cli": "^3.1.2",
"webpack-dev-server": "^3.7.0"
}
}

View File

@ -1 +0,0 @@
<div *ngIf="message" [ngClass]="message.cssClass">{{message.text}}</div>

View File

@ -1,32 +0,0 @@
import { Component, OnInit, OnDestroy } from '@angular/core';
import { Subscription } from 'rxjs';
import { AlertService } from '@/_services';
@Component({ selector: 'alert', templateUrl: 'alert.component.html' })
export class AlertComponent implements OnInit, OnDestroy {
private subscription: Subscription;
message: any;
constructor(private alertService: AlertService) { }
ngOnInit() {
this.subscription = this.alertService.getAlert()
.subscribe(message => {
switch (message && message.type) {
case 'success':
message.cssClass = 'alert alert-success';
break;
case 'error':
message.cssClass = 'alert alert-danger';
break;
}
this.message = message;
});
}
ngOnDestroy() {
this.subscription.unsubscribe();
}
}

View File

@ -1 +0,0 @@
export * from './alert.component';

View File

@ -1,4 +0,0 @@
// global application styles
a {
cursor: pointer;
}

View File

@ -1,24 +0,0 @@
import { Injectable } from '@angular/core';
import { Router, CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot } from '@angular/router';
import { AuthenticationService } from '@/_services';
@Injectable({ providedIn: 'root' })
export class AuthGuard implements CanActivate {
constructor(
private router: Router,
private authenticationService: AuthenticationService
) {}
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
const currentUser = this.authenticationService.currentUserValue;
if (currentUser) {
// authorised so return true
return true;
}
// not logged in so redirect to login page with the return url
this.router.navigate(['/login'], { queryParams: { returnUrl: state.url }});
return false;
}
}

View File

@ -1,24 +0,0 @@
import { Injectable } from '@angular/core';
import { HttpRequest, HttpHandler, HttpEvent, HttpInterceptor } from '@angular/common/http';
import { Observable, throwError } from 'rxjs';
import { catchError } from 'rxjs/operators';
import { AuthenticationService } from '@/_services';
@Injectable()
export class ErrorInterceptor implements HttpInterceptor {
constructor(private authenticationService: AuthenticationService) {}
intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
return next.handle(request).pipe(catchError(err => {
if (err.status === 401) {
// auto logout if 401 response returned from api
this.authenticationService.logout();
location.reload(true);
}
const error = err.error.message || err.statusText;
return throwError(error);
}))
}
}

View File

@ -1,109 +0,0 @@
import { Injectable } from '@angular/core';
import { HttpRequest, HttpResponse, HttpHandler, HttpEvent, HttpInterceptor, HTTP_INTERCEPTORS } from '@angular/common/http';
import { Observable, of, throwError } from 'rxjs';
import { delay, mergeMap, materialize, dematerialize } from 'rxjs/operators';
// array in local storage for registered users
let users = JSON.parse(localStorage.getItem('users')) || [];
@Injectable()
export class FakeBackendInterceptor implements HttpInterceptor {
intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
const { url, method, headers, body } = request;
// wrap in delayed observable to simulate server api call
return of(null)
.pipe(mergeMap(handleRoute))
.pipe(materialize()) // call materialize and dematerialize to ensure delay even if an error is thrown (https://github.com/Reactive-Extensions/RxJS/issues/648)
.pipe(delay(500))
.pipe(dematerialize());
function handleRoute() {
switch (true) {
case url.endsWith('/users/authenticate') && method === 'POST':
return authenticate();
case url.endsWith('/users/register') && method === 'POST':
return register();
case url.endsWith('/users') && method === 'GET':
return getUsers();
case url.match(/\/users\/\d+$/) && method === 'DELETE':
return deleteUser();
default:
// pass through any requests not handled above
return next.handle(request);
}
}
// route functions
function authenticate() {
const { username, password } = body;
const user = users.find(x => x.username === username && x.password === password);
if (!user) return error('Username or password is incorrect');
return ok({
id: user.id,
username: user.username,
firstName: user.firstName,
lastName: user.lastName,
token: 'fake-jwt-token'
})
}
function register() {
const user = body
if (users.find(x => x.username === user.username)) {
return error('Username "' + user.username + '" is already taken')
}
user.id = users.length ? Math.max(...users.map(x => x.id)) + 1 : 1;
users.push(user);
localStorage.setItem('users', JSON.stringify(users));
return ok();
}
function getUsers() {
if (!isLoggedIn()) return unauthorized();
return ok(users);
}
function deleteUser() {
if (!isLoggedIn()) return unauthorized();
users = users.filter(x => x.id !== idFromUrl());
localStorage.setItem('users', JSON.stringify(users));
return ok();
}
// helper functions
function ok(body?) {
return of(new HttpResponse({ status: 200, body }))
}
function error(message) {
return throwError({ error: { message } });
}
function unauthorized() {
return throwError({ status: 401, error: { message: 'Unauthorised' } });
}
function isLoggedIn() {
return headers.get('Authorization') === 'Bearer fake-jwt-token';
}
function idFromUrl() {
const urlParts = url.split('/');
return parseInt(urlParts[urlParts.length - 1]);
}
}
}
export const fakeBackendProvider = {
// use fake backend in place of Http service for backend-less development
provide: HTTP_INTERCEPTORS,
useClass: FakeBackendInterceptor,
multi: true
};

View File

@ -1,4 +0,0 @@
export * from './auth.guard';
export * from './error.interceptor';
export * from './jwt.interceptor';
export * from './fake-backend';

View File

@ -1,24 +0,0 @@
import { Injectable } from '@angular/core';
import { HttpRequest, HttpHandler, HttpEvent, HttpInterceptor } from '@angular/common/http';
import { Observable } from 'rxjs';
import { AuthenticationService } from '@/_services';
@Injectable()
export class JwtInterceptor implements HttpInterceptor {
constructor(private authenticationService: AuthenticationService) {}
intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
// add authorization header with jwt token if available
let currentUser = this.authenticationService.currentUserValue;
if (currentUser && currentUser.token) {
request = request.clone({
setHeaders: {
Authorization: `Bearer ${currentUser.token}`
}
});
}
return next.handle(request);
}
}

View File

@ -1,8 +0,0 @@
export class Challange {
id: string
name: string
description: string
currentAmount: number
numberOfObservators: number
sponsoredBy: string
}

View File

@ -1,4 +0,0 @@
export class Group {
id: string;
name: string;
}

View File

@ -1,3 +0,0 @@
export * from './user';
export * from './group';
export * from './challange';

View File

@ -1,8 +0,0 @@
export class User {
id: number;
username: string;
password: string;
firstName: string;
lastName: string;
token: string;
}

View File

@ -1,43 +0,0 @@
import { Injectable } from '@angular/core';
import { Router, NavigationStart } from '@angular/router';
import { Observable, Subject } from 'rxjs';
@Injectable({ providedIn: 'root' })
export class AlertService {
private subject = new Subject<any>();
private keepAfterRouteChange = false;
constructor(private router: Router) {
// clear alert messages on route change unless 'keepAfterRouteChange' flag is true
this.router.events.subscribe(event => {
if (event instanceof NavigationStart) {
if (this.keepAfterRouteChange) {
// only keep for a single route change
this.keepAfterRouteChange = false;
} else {
// clear alert message
this.clear();
}
}
});
}
getAlert(): Observable<any> {
return this.subject.asObservable();
}
success(message: string, keepAfterRouteChange = false) {
this.keepAfterRouteChange = keepAfterRouteChange;
this.subject.next({ type: 'success', text: message });
}
error(message: string, keepAfterRouteChange = false) {
this.keepAfterRouteChange = keepAfterRouteChange;
this.subject.next({ type: 'error', text: message });
}
clear() {
// clear by calling subject.next() without parameters
this.subject.next();
}
}

View File

@ -1,37 +0,0 @@
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { BehaviorSubject, Observable } from 'rxjs';
import { map } from 'rxjs/operators';
import { User } from '@/_models';
@Injectable({ providedIn: 'root' })
export class AuthenticationService {
private currentUserSubject: BehaviorSubject<User>;
public currentUser: Observable<User>;
constructor(private http: HttpClient) {
this.currentUserSubject = new BehaviorSubject<User>(JSON.parse(localStorage.getItem('currentUser')));
this.currentUser = this.currentUserSubject.asObservable();
}
public get currentUserValue(): User {
return this.currentUserSubject.value;
}
login(username, password) {
return this.http.post<any>(`${config.apiUrl}/users/authenticate`, { username, password })
.pipe(map(user => {
// store user details and jwt token in local storage to keep user logged in between page refreshes
localStorage.setItem('currentUser', JSON.stringify(user));
this.currentUserSubject.next(user);
return user;
}));
}
logout() {
// remove user from local storage and set current user to null
localStorage.removeItem('currentUser');
this.currentUserSubject.next(null);
}
}

View File

@ -1,47 +0,0 @@
import { Challange } from '@/_models'
import { Injectable } from '@angular/core';
@Injectable({ providedIn: 'root' })
export class ChallangesService {
challanges: Challange[] = [
{ id: "1", name: 'Dwa litry Coli w 20 sekund!', description: 'Czy dasz radę wypić całą butelkę coli w 20 sekund? Zmierz się!', currentAmount: 500, numberOfObservators: 30, sponsoredBy: "Coca-Cola" },
{ id: "2", name: 'Zdobądź numer swojej nauczycielki!', description: 'Myślisz, ze dobrze radzisz sobie w kontaktach z płcią przeciwną? Skoro tak, to zdobądź numer swojej nauczycielki / nauczyciela!', currentAmount: 300, numberOfObservators: 50, sponsoredBy: null },
{ id: "3", name: 'Stanie na rękach na sedesie!', description: 'Myślisz, ze jesteś zwinny? Jesteś dobrym atletą? Przekonaj nas o tym, wykonując stanie na rękach w zupełnie nieoczywistym miejscu!', currentAmount: 50, numberOfObservators: 15, sponsoredBy: null }
]
constructor() {
}
getChallange(challangeId) {
return this.challanges.filter(
challange => challange.id === challangeId
)[0]
}
addChallange(challangeInfo) {
console.log(challangeInfo)
const id = this.getId()
let newChallange: Challange = {id: id, name: challangeInfo.firstName, description: challangeInfo.lastName, sponsoredBy: challangeInfo.username, currentAmount: 0, numberOfObservators: 0}
this.challanges.push(newChallange)
}
getId() {
const newId = this.challanges[this.challanges.length-1].id + 1
return newId
}
addMoneyToChallange(challangeId, amount) {
let item = this.getChallange(challangeId)
let index = this.challanges.indexOf(item)
let newItem = { id: item.id, name: item.name, description: item.description, currentAmount: item.currentAmount + amount, numberOfObservators: item.numberOfObservators, sponsoredBy: item.sponsoredBy }
this.challanges[index] = newItem
}
observeChallange(challangeId) {
}
}

View File

@ -1,56 +0,0 @@
import { Injectable } from '@angular/core';
import { Group } from '@/_models';
@Injectable({ providedIn: 'root' })
export class GroupsService {
myGroups: Group[] = [
{ id: "1", name: "miszczowie" },
{ id: "2", name: "najlepsza grupa ever" },
{ id: "3", name: "najlepsiejsi" }
]
allGroups: Group[] = [
{ id: "1", name: "miszczowie" },
{ id: "2", name: "najlepsza grupa ever" },
{ id: "3", name: "najlepsiejsi" },
{ id: "4", name: "Super grupa" },
{ id: "5", name: "Zwycięzcy" },
{ id: "6", name: "Niezwycięzeni" },
]
constructor() {
// localStorage.setItem("allGroups", JSON.stringify(this.allGroups))
let myGroups = localStorage.getItem("myGroups")
let g = myGroups == null ? [] : JSON.parse(myGroups)
this.myGroups = g
}
getGroup(groupId) {
return this.allGroups.filter(
group => group.id === groupId
)[0]
}
doIBelong(groupId) {
if (this.myGroups == null) {
return false
}
if (this.myGroups.filter(
group => group.id === groupId
)[0] == null) {
return false
}
else {
return true
}
}
joinGroup(groupId) {
const group = this.getGroup(groupId)
let myGroups = this.myGroups == null ? [] : this.myGroups
myGroups.push(group)
this.myGroups = myGroups
localStorage.setItem("myGroups", JSON.stringify(myGroups))
}
}

View File

@ -1,5 +0,0 @@
export * from './alert.service';
export * from './authentication.service';
export * from './user.service';
export * from './groups.service';
export * from './challanges.service';

View File

@ -1,21 +0,0 @@
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { User } from '@/_models';
@Injectable({ providedIn: 'root' })
export class UserService {
constructor(private http: HttpClient) { }
getAll() {
return this.http.get<User[]>(`${config.apiUrl}/users`);
}
register(user: User) {
return this.http.post(`${config.apiUrl}/users/register`, user);
}
delete(id: number) {
return this.http.delete(`${config.apiUrl}/users/${id}`);
}
}

View File

@ -1,40 +0,0 @@
<div class="jumbotron">
<div class="container">
<div class="row">
<div class="col-sm-6 offset-sm-3">
<h2>Dodaj wyzwanie</h2>
<form [formGroup]="registerForm" (ngSubmit)="onSubmit()">
<div class="form-group">
<label for="firstName">Nazwa</label>
<input type="text" formControlName="firstName" class="form-control"
[ngClass]="{ 'is-invalid': submitted && f.firstName.errors }" />
<div *ngIf="submitted && f.firstName.errors" class="invalid-feedback">
<div *ngIf="f.firstName.errors.required">Nazwa jest wymagana</div>
</div>
</div>
<div class="form-group">
<label for="lastName">Opis</label>
<input type="text" formControlName="lastName" class="form-control"
[ngClass]="{ 'is-invalid': submitted && f.lastName.errors }" />
<div *ngIf="submitted && f.lastName.errors" class="invalid-feedback">
<div *ngIf="f.lastName.errors.required">Opis jest wymagany</div>
</div>
</div>
<div class="form-group">
<label for="username">Sponsor (opcjonalnie)</label>
<input type="text" formControlName="username" class="form-control"
[ngClass]="{ 'is-invalid': submitted && f.username.errors }" />
</div>
<div class="form-group">
<button [disabled]="loading" class="btn btn-primary">
<span *ngIf="loading" class="spinner-border spinner-border-sm mr-1"></span>
Dodaj!
</button>
<a routerLink="/login" class="btn btn-link">Anuluj</a>
</div>
</form>
</div>
</div>
</div>
</div>

View File

@ -1,46 +0,0 @@
import { Component, OnInit } from '@angular/core';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
import { Router } from '@angular/router';
import { ChallangesService } from '@/_services';
import { first } from 'rxjs/operators';
@Component({ templateUrl: 'addChallange.component.html' })
export class AddChallangeComponent implements OnInit {
registerForm: FormGroup;
loading = false;
submitted = false;
constructor(
private formBuilder: FormBuilder,
private router: Router,
private challangeService: ChallangesService
) {
}
ngOnInit() {
this.registerForm = this.formBuilder.group({
firstName: ['', Validators.required],
lastName: ['', Validators.required],
username: ['', Validators.required],
});
}
get f() { return this.registerForm.controls; }
onSubmit() {
this.submitted = true;
// stop here if form is invalid
if (this.registerForm.invalid) {
return;
}
this.loading = true;
this.challangeService.addChallange(this.registerForm.value)
this.loading = false
this.router.navigate(["/"])
}
}

View File

@ -1 +0,0 @@
export * from './addChallange.component';

View File

@ -1,15 +0,0 @@
<!-- nav -->
<nav class="navbar navbar-expand navbar-dark bg-dark" *ngIf="currentUser">
<div class="navbar-nav">
<img style="height: 50px; width: 200px;"
src="https://m.media-amazon.com/images/M/MV5BYTY3NDVmZDYtNDg5OS00NTVjLTk0NWItZjhlMTkxMWI1OTRhXkEyXkFqcGdeQXVyNTkzOTM0Nzg@._V1_SX1777_CR0,0,1777,539_AL_.jpg">
<a class="nav-item nav-link" routerLink="/">Challenge accepted</a>
<a class="nav-item nav-link" routerLink="/groups">Grupy</a>
<a class="nav-item nav-link" routerLink="/rank_challanges">Oceniaj wyzwania</a>
<a class="nav-item nav-link" (click)="logout()">Logout</a>
</div>
</nav>
<alert></alert>
<router-outlet></router-outlet>

View File

@ -1,24 +0,0 @@
import { Component } from '@angular/core';
import { Router } from '@angular/router';
import { AuthenticationService } from './_services';
import { User } from './_models';
import './_content/app.less';
@Component({ selector: 'app', templateUrl: 'app.component.html' })
export class AppComponent {
currentUser: User;
constructor(
private router: Router,
private authenticationService: AuthenticationService
) {
this.authenticationService.currentUser.subscribe(x => this.currentUser = x);
}
logout() {
this.authenticationService.logout();
this.router.navigate(['/login']);
}
}

View File

@ -1,56 +0,0 @@
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { ReactiveFormsModule } from '@angular/forms';
import { HttpClientModule, HTTP_INTERCEPTORS } from '@angular/common/http';
import { FormsModule } from '@angular/forms';
// used to create fake backend
import { fakeBackendProvider } from './_helpers';
import { appRoutingModule } from './app.routing';
import { JwtInterceptor, ErrorInterceptor } from './_helpers';
import { AppComponent } from './app.component';
import { HomeComponent } from './home';
import { LoginComponent } from './login';
import { GroupComponent } from './group';
import { GroupsComponent } from './groups';
import { RegisterComponent } from './register';
import { AlertComponent } from './_components';
import { ChallangeComponent } from './challange/challange.component';
import { AddChallangeComponent } from './addChallange';
import { FinishChallangeComponent } from './finishChallange';
import { RankChallangesComponent } from './rank_challanges';
import { RankChallangeComponent } from './rank_challange';
@NgModule({
imports: [
BrowserModule,
ReactiveFormsModule,
HttpClientModule,
appRoutingModule,
FormsModule
],
declarations: [
AppComponent,
HomeComponent,
LoginComponent,
RegisterComponent,
GroupComponent,
GroupsComponent,
AlertComponent,
ChallangeComponent,
AddChallangeComponent,
FinishChallangeComponent,
RankChallangesComponent,
RankChallangeComponent
],
providers: [
{ provide: HTTP_INTERCEPTORS, useClass: JwtInterceptor, multi: true },
{ provide: HTTP_INTERCEPTORS, useClass: ErrorInterceptor, multi: true },
// provider used to create fake backend
fakeBackendProvider
],
bootstrap: [AppComponent]
})
export class AppModule { };

View File

@ -1,31 +0,0 @@
import { Routes, RouterModule } from '@angular/router';
import { HomeComponent } from './home';
import { LoginComponent } from './login';
import { RegisterComponent } from './register';
import { GroupsComponent } from './groups';
import { GroupComponent } from './group';
import { AuthGuard } from './_helpers';
import { ChallangeComponent } from './challange';
import { AddChallangeComponent } from './addChallange';
import { FinishChallangeComponent } from './finishChallange';
import { RankChallangesComponent } from './rank_challanges';
import { RankChallangeComponent } from './rank_challange';
const routes: Routes = [
{ path: '', component: HomeComponent, canActivate: [AuthGuard] },
{ path: 'login', component: LoginComponent },
{ path: 'register', component: RegisterComponent },
{ path: 'groups', component: GroupsComponent, canActivate: [AuthGuard] },
{ path: 'group/:id', component: GroupComponent, canActivate: [AuthGuard] },
{ path: 'challange/:id', component: ChallangeComponent, canActivate: [AuthGuard] },
{ path: 'add_challange', component: AddChallangeComponent, canActivate: [AuthGuard] },
{ path: 'finish_challange/:id', component: FinishChallangeComponent, canActivate: [AuthGuard] },
{ path: 'rank_challanges', component: RankChallangesComponent, canActivate: [AuthGuard] },
{ path: 'rank_challange/:id', component: RankChallangeComponent, canActivate: [AuthGuard]},
// otherwise redirect to home
{ path: '**', redirectTo: '' }
];
export const appRoutingModule = RouterModule.forRoot(routes);

View File

@ -1,54 +0,0 @@
<div class="container">
<div class="jumbotron">
<div class="row justify-content-md-center">
<h2>{{challange.name}}</h2>
</div>
<div class="row" style="padding-top: 50px;">
<div class="col-md-8">
<h4>Opis</h4>
{{challange.description}}
</div>
<div class="col-md-4">
<h4>Dodatkowe informacje:</h4>
<p>Obecna kwota: <b>{{challange.currentAmount}}zł</b></p>
<p>Liczba obserwujących: <b>{{challange.numberOfObservators}}</b></p>
<p *ngIf="challange.sponsoredBy">Oficjalny sponsor: <b>{{challange.sponsoredBy}}</b></p>
</div>
</div>
<div class="row" style="padding-top: 50px;">
<div class="col-md-4">
<h6>Dodaj pieniądze</h6>
<button type="button" class="btn btn-primary" (click)="addMoney(5)">5zł</button>
<button type="button" class="btn btn-primary" (click)="addMoney(10)">10zł</button>
<button type="button" class="btn btn-primary" (click)="addMoney(20)">20zł</button>
</div>
<div class="col-md-4"><button type="button" class="btn btn-info" (click)="observe()">Obserwuj</button></div>
<div class="col-md-4" *ngIf="!taken"><button type="button" class="btn btn-success" (click)="take()">Podejmij się!</button></div>
<div class="col-md-4" *ngIf="taken"><button type="button" class="btn btn-success" (click)="finish()">Zakończ wyzwanie!</button></div>
</div>
</div>
<div class="container">
<h2>Komentarze</h2>
<div class="row">
<div class="col-md-3">
Autor
<input type="text" [(ngModel)]="author">
</div>
<div class="col-md-7">
<textarea type="text" [(ngModel)]="body" style="width: 100%;"></textarea>
</div>
<div class="col-md-2">
<button (click)="addComment()">Dodaj komentarz</button>
</div>
</div>
<div class="row">
<div class="col-md-2"><b>Autor</b></div>
<div class="col-md-10"><b>Komentarz</b></div>
</div>
<div *ngFor="let comment of comments" class="row" style="padding-top: 20px;">
<div class="col-md-2">{{comment.author}}</div>
<div class="col-md-10">{{comment.body}}</div>
</div>
</div>
</div>

View File

@ -1,54 +0,0 @@
import { Component, OnInit } from '@angular/core';
import { Router, ActivatedRoute } from '@angular/router';
import { Challange } from '@/_models';
import { ChallangesService } from '@/_services';
@Component({ templateUrl: 'challange.component.html' })
export class ChallangeComponent implements OnInit {
comments = [
{author: "szalony", body: "Wow, ale opcja!!!!!"},
{author: "krejzol", body: "Nie wierzę!!!!!"},
]
challange: Challange = null
observing = false
taken = false
author: string = '';
body: string = '';
constructor(
private route: ActivatedRoute,
private router: Router,
private service: ChallangesService
) {
}
ngOnInit() {
const challangeId = this.route.snapshot.paramMap.get('id')
this.challange = this.service.getChallange(challangeId)
}
addMoney(amount) {
this.service.addMoneyToChallange(this.challange.id, amount)
this.challange.currentAmount += amount
}
observe() {
if (this.observing) return
this.observing = true
this.challange.numberOfObservators += 1
}
addComment() {
this.comments.push({author: this.author, body: this.body})
}
take() {
this.taken = true
}
finish() {
this.router.navigate(['/finish_challange/' + this.challange.id])
}
}

View File

@ -1 +0,0 @@
export * from './challange.component';

View File

@ -1,20 +0,0 @@
<div class="container">
<div class="jumbotron" *ngIf="!finished">
<h1>Konczenie wyzwania</h1>
<div class="row">
<div class="col-md-6">
<input #fileInput type='file'/>
</div>
<div class="col-md-6">
<button class="btn btn-success" (click)="finish()">Wyślij</button>
</div>
</div>
</div>
<div class="jumbotron" *ngIf="finished">
<h2>Super!</h2>
<div class="row">
<p>Wysłaliśmy plik do wyzywającego! Zawiadomimy Cię o akceptacji!</p>
</div>
</div>
</div>

View File

@ -1,24 +0,0 @@
import { Component, OnInit } from '@angular/core';
import { Router, ActivatedRoute } from '@angular/router';
import { Challange } from '@/_models';
import { ChallangesService } from '@/_services';
@Component({ templateUrl: 'finishChallange.component.html' })
export class FinishChallangeComponent implements OnInit {
finished = false
constructor(
private route: ActivatedRoute,
private router: Router,
private service: ChallangesService
) {
}
ngOnInit() {
}
finish() {
this.finished = true
}
}

View File

@ -1 +0,0 @@
export * from './finishChallange.component';

View File

@ -1,30 +0,0 @@
<div class='jumbotron'>
<div class="container">
<div class="row justify-content-md-center">
<h1>Grupa <b>{{group.name}}</b></h1>
</div>
<div class="row">
<div class="col-sm-8 offset-sm-2">
<h2>Lista członków</h2>
<div class="list-group">
<a class="list-group-item list-group-item-action">Janek</a>
<a class="list-group-item list-group-item-action">Krzychu</a>
<a class="list-group-item list-group-item-action">Kuba</a>
<a class="list-group-item list-group-item-action">Adam</a>
</div>
</div>
</div>
<div class="row justify-content-md-center" style="padding: 40px;">
<div class="col-sm-6 offset-sm-3" *ngIf="doIBelong()">
<button type="button" class="btn btn-danger" (click)="leaveGroup()">Opuść grupę</button>
<button type="button" class="btn btn-success">Nalezysz do grupy</button>
</div>
<div class="col-sm-6 offset-sm-3" *ngIf="!doIBelong()">
<button type="button" class="btn btn-primary" (click)="joinGroup()">Dołącz do grupy</button>
</div>
</div>
</div>
</div>

View File

@ -1,30 +0,0 @@
import { Component, OnInit } from '@angular/core';
import { Router, ActivatedRoute } from '@angular/router';
import { GroupsService } from '@/_services';
import { Group } from '@/_models';
@Component({ templateUrl: 'group.component.html' })
export class GroupComponent implements OnInit {
group: Group = null
constructor(
private route: ActivatedRoute,
private router: Router,
private service: GroupsService
) {
}
ngOnInit() {
const groupId = this.route.snapshot.paramMap.get('id')
this.group = this.service.getGroup(groupId)
}
doIBelong() {
return this.service.doIBelong(this.group.id)
}
joinGroup() {
this.service.joinGroup(this.group.id)
}
}

View File

@ -1 +0,0 @@
export * from './group.component';

View File

@ -1,28 +0,0 @@
<div class="container">
<div class="row">
<div class="col-sm-6">
<h1 class="display-4">Twoje Grupy</h1>
<div class="list-group">
<a class="list-group-item list-group-item-action" *ngFor="let group of myGroups" (click)="goToGroup(group.id)">
{{group.name}}
</a>
</div>
</div>
<div class="col-sm-6">
<h1 class="display-4">Wszystkie Grupy</h1>
<div class="list-group">
<a class="list-group-item list-group-item-action" *ngFor="let group of allGroups" (click)="goToGroup(group.id)">
{{group.name}}
</a>
</div>
</div>
</div>
<div class="row justify-content-md-center" style="padding: 40px;">
<div class="col-sm-6 offset-sm-3">
<button type="button" class="btn btn-primary" (click)="addGroup()">Stwórz nową grupę</button>
</div>
</div>
</div>

View File

@ -1,29 +0,0 @@
import { Component, OnInit } from '@angular/core';
import { Router } from '@angular/router';
import { GroupsService } from '@/_services';
@Component({ templateUrl: 'groups.component.html' })
export class GroupsComponent implements OnInit {
myGroups = []
allGroups = []
constructor(
private router: Router,
private groupsService: GroupsService
) {
this.myGroups = groupsService.myGroups
this.allGroups = groupsService.allGroups
}
ngOnInit() {
}
goToGroup(groupId) {
this.router.navigate(['/group/' + groupId])
}
addGroup() {
}
}

View File

@ -1 +0,0 @@
export * from './groups.component';

View File

@ -1,24 +0,0 @@
<div class="jumbotron">
<div class="container">
<div class="row">
<div class="col-sm-8 offset-sm-2">
<h2>Hi {{currentUser.firstName}}, Challenge Accepted!</h2>
<h3>Obecne wyzwania:</h3>
<div class="list-group">
<a class="list-group-item list-group-item-action" *ngFor="let challange of challanges"
(click)="goToChallange(challange.id)">
{{challange.name}}
</a>
</div>
</div>
</div>
<div class="row" style="padding-top: 50px;">
<div class="col-md-4 offset-md-8">
<button type="button" class="btn btn-primary" (click)="addChallange()">Dodaj nowe wyzwanie!</button>
</div>
</div>
</div>
</div>

View File

@ -1,32 +0,0 @@
import { Component, OnInit } from '@angular/core';
import { User, Challange } from '@/_models';
import { AuthenticationService, ChallangesService } from '@/_services';
import { Router } from '@angular/router';
@Component({ templateUrl: 'home.component.html' })
export class HomeComponent implements OnInit {
currentUser: User;
users = [];
challanges: Challange[] = []
constructor(
private router: Router,
private authenticationService: AuthenticationService,
private challangeService: ChallangesService
) {
this.currentUser = this.authenticationService.currentUserValue;
}
goToChallange(challangeId) {
this.router.navigate(['/challange/' + challangeId])
}
addChallange() {
this.router.navigate(['/add_challange'])
}
ngOnInit() {
this.challanges = this.challangeService.challanges
}
}

View File

@ -1 +0,0 @@
export * from './home.component';

View File

@ -1 +0,0 @@
export * from './login.component';

View File

@ -1,36 +0,0 @@
<div class="jumbotron">
<div class="container">
<div class="row">
<div class="col-sm-6 offset-sm-3">
<h1 style="padding: 70px;">Challenge Accepted</h1>
<h2>Login</h2>
<form [formGroup]="loginForm" (ngSubmit)="onSubmit()">
<div class="form-group">
<label for="username">Username</label>
<input type="text" formControlName="username" class="form-control"
[ngClass]="{ 'is-invalid': submitted && f.username.errors }" />
<div *ngIf="submitted && f.username.errors" class="invalid-feedback">
<div *ngIf="f.username.errors.required">Username is required</div>
</div>
</div>
<div class="form-group">
<label for="password">Password</label>
<input type="password" formControlName="password" class="form-control"
[ngClass]="{ 'is-invalid': submitted && f.password.errors }" />
<div *ngIf="submitted && f.password.errors" class="invalid-feedback">
<div *ngIf="f.password.errors.required">Password is required</div>
</div>
</div>
<div class="form-group">
<button [disabled]="loading" class="btn btn-primary">
<span *ngIf="loading" class="spinner-border spinner-border-sm mr-1"></span>
Login
</button>
<a routerLink="/register" class="btn btn-link">Register</a>
</div>
</form>
</div>
</div>
</div>
</div>

View File

@ -1,64 +0,0 @@
import { Component, OnInit } from '@angular/core';
import { Router, ActivatedRoute } from '@angular/router';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
import { first } from 'rxjs/operators';
import { AlertService, AuthenticationService } from '@/_services';
@Component({ templateUrl: 'login.component.html' })
export class LoginComponent implements OnInit {
loginForm: FormGroup;
loading = false;
submitted = false;
returnUrl: string;
constructor(
private formBuilder: FormBuilder,
private route: ActivatedRoute,
private router: Router,
private authenticationService: AuthenticationService,
private alertService: AlertService
) {
// redirect to home if already logged in
if (this.authenticationService.currentUserValue) {
this.router.navigate(['/']);
}
}
ngOnInit() {
this.loginForm = this.formBuilder.group({
username: ['', Validators.required],
password: ['', Validators.required]
});
// get return url from route parameters or default to '/'
this.returnUrl = this.route.snapshot.queryParams['returnUrl'] || '/';
}
// convenience getter for easy access to form fields
get f() { return this.loginForm.controls; }
onSubmit() {
this.submitted = true;
// reset alerts on submit
this.alertService.clear();
// stop here if form is invalid
if (this.loginForm.invalid) {
return;
}
this.loading = true;
this.authenticationService.login(this.f.username.value, this.f.password.value)
.pipe(first())
.subscribe(
data => {
this.router.navigate([this.returnUrl]);
},
error => {
this.alertService.error(error);
this.loading = false;
});
}
}

View File

@ -1 +0,0 @@
export * from './rank_challange.component';

View File

@ -1,35 +0,0 @@
<div class="container">
<div class="jumbotron">
<div class="row" style="text-align: center;">
<h1 style="margin-left: 20%; padding: 50px;">{{challange.name}}</h1>
</div>
<div class="row">
<div class="col-sm-4">
<p> Nadesłane przez: <b>Świr1.9TDI</b></p>
<p>Data nadesłania: <b>20.01.2020</b></p>
<button *ngIf="!voted" (click)="vote()" class="btn btn-success">Zagłosuj!</button>
<button *ngIf="voted" disabled class="btn btn-success">Zagłosowane!!</button>
</div>
<div class="col-sm-8">
<!-- <iframe width="420" height="315" -->
<iframe width="640" height="480"
src="https://www.youtube.com/embed/tgbNymZ7vqY">
</iframe>
</div>
</div>
<div class="row" style="padding-top: 50px;">
<div class="col-sm-4">
<p> Nadesłane przez: <b>JestemSuper</b></p>
<p>Data nadesłania: <b>19.01.2020</b></p>
<button *ngIf="!voted" (click)="vote()" class="btn btn-success">Zagłosuj!</button>
<button *ngIf="voted" disabled class="btn btn-success">Zagłosowane!!</button>
</div>
<div class="col-sm-8">
<iframe width="640" height="480"
src="https://www.youtube.com/embed/17vTLSkXTOo">
</iframe>
</div>
</div>
</div>
</div>

View File

@ -1,28 +0,0 @@
import { Component, OnInit } from '@angular/core';
import { User, Challange } from '@/_models';
import { AuthenticationService, ChallangesService } from '@/_services';
import { Router, ActivatedRoute } from '@angular/router';
@Component({ templateUrl: 'rank_challange.component.html' })
export class RankChallangeComponent implements OnInit {
challange = {}
voted = false
constructor(
private service: ChallangesService,
private route: ActivatedRoute
) {
}
ngOnInit() {
const challangeId = this.route.snapshot.paramMap.get('id')
this.challange = this.service.getChallange(challangeId)
}
vote() {
this.voted = true
}
}

View File

@ -1 +0,0 @@
export * from './rank_challanges.component';

View File

@ -1,15 +0,0 @@
<div class="container">
<div class="jumbotron">
<div class="row">
<div class="col-sm-8 offset-sm-2">
<h2>Wyzwania, które sponsorujesz</h2>
<div class="list-group">
<a class="list-group-item list-group-item-action" *ngFor="let challange of challanges"
(click)="goToChallange(challange.id)">
{{challange.name}}
</a>
</div>
</div>
</div>
</div>
</div>

View File

@ -1,23 +0,0 @@
import { Component, OnInit } from '@angular/core';
import { ChallangesService } from '@/_services';
import { Router } from '@angular/router';
@Component({ templateUrl: 'rank_challanges.component.html'})
export class RankChallangesComponent implements OnInit {
challanges = []
constructor(
private challangeService: ChallangesService,
private router: Router
) {
}
ngOnInit() {
this.challanges = this.challangeService.challanges
}
goToChallange(challangeId) {
this.router.navigate(['/rank_challange/' + challangeId])
}
}

View File

@ -1 +0,0 @@
export * from './register.component';

View File

@ -1,51 +0,0 @@
<div class="jumbotron">
<div class="container">
<div class="row">
<div class="col-sm-6 offset-sm-3">
<h2>Register</h2>
<form [formGroup]="registerForm" (ngSubmit)="onSubmit()">
<div class="form-group">
<label for="firstName">First Name</label>
<input type="text" formControlName="firstName" class="form-control"
[ngClass]="{ 'is-invalid': submitted && f.firstName.errors }" />
<div *ngIf="submitted && f.firstName.errors" class="invalid-feedback">
<div *ngIf="f.firstName.errors.required">First Name is required</div>
</div>
</div>
<div class="form-group">
<label for="lastName">Last Name</label>
<input type="text" formControlName="lastName" class="form-control"
[ngClass]="{ 'is-invalid': submitted && f.lastName.errors }" />
<div *ngIf="submitted && f.lastName.errors" class="invalid-feedback">
<div *ngIf="f.lastName.errors.required">Last Name is required</div>
</div>
</div>
<div class="form-group">
<label for="username">Username</label>
<input type="text" formControlName="username" class="form-control"
[ngClass]="{ 'is-invalid': submitted && f.username.errors }" />
<div *ngIf="submitted && f.username.errors" class="invalid-feedback">
<div *ngIf="f.username.errors.required">Username is required</div>
</div>
</div>
<div class="form-group">
<label for="password">Password</label>
<input type="password" formControlName="password" class="form-control"
[ngClass]="{ 'is-invalid': submitted && f.password.errors }" />
<div *ngIf="submitted && f.password.errors" class="invalid-feedback">
<div *ngIf="f.password.errors.required">Password is required</div>
<div *ngIf="f.password.errors.minlength">Password must be at least 6 characters</div>
</div>
</div>
<div class="form-group">
<button [disabled]="loading" class="btn btn-primary">
<span *ngIf="loading" class="spinner-border spinner-border-sm mr-1"></span>
Register
</button>
<a routerLink="/login" class="btn btn-link">Cancel</a>
</div>
</form>
</div>
</div>
</div>
</div>

View File

@ -1,63 +0,0 @@
import { Component, OnInit } from '@angular/core';
import { Router } from '@angular/router';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
import { first } from 'rxjs/operators';
import { AlertService, UserService, AuthenticationService } from '@/_services';
@Component({ templateUrl: 'register.component.html' })
export class RegisterComponent implements OnInit {
registerForm: FormGroup;
loading = false;
submitted = false;
constructor(
private formBuilder: FormBuilder,
private router: Router,
private authenticationService: AuthenticationService,
private userService: UserService,
private alertService: AlertService
) {
// redirect to home if already logged in
if (this.authenticationService.currentUserValue) {
this.router.navigate(['/']);
}
}
ngOnInit() {
this.registerForm = this.formBuilder.group({
firstName: ['', Validators.required],
lastName: ['', Validators.required],
username: ['', Validators.required],
password: ['', [Validators.required, Validators.minLength(6)]]
});
}
// convenience getter for easy access to form fields
get f() { return this.registerForm.controls; }
onSubmit() {
this.submitted = true;
// reset alerts on submit
this.alertService.clear();
// stop here if form is invalid
if (this.registerForm.invalid) {
return;
}
this.loading = true;
this.userService.register(this.registerForm.value)
.pipe(first())
.subscribe(
data => {
this.alertService.success('Registration successful', true);
this.router.navigate(['/login']);
},
error => {
this.alertService.error(error);
this.loading = false;
});
}
}

View File

@ -1,14 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<base href="/" />
<title>Challenge Accepted</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- bootstrap css -->
<link href="//cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.3.1/css/bootstrap.min.css" rel="stylesheet" />
</head>
<body>
<app>Loading...</app>
</body>
</html>

View File

@ -1,6 +0,0 @@
import './polyfills';
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { AppModule } from './app/app.module';
platformBrowserDynamic().bootstrapModule(AppModule);

View File

@ -1,2 +0,0 @@
import 'core-js/features/reflect';
import 'zone.js/dist/zone';

View File

@ -1,2 +0,0 @@
// so the typescript compiler doesn't complain about the global config object
declare var config: any;

View File

@ -1,13 +0,0 @@
{
"compilerOptions": {
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"target": "ES5",
"baseUrl": "src",
"paths": {
"@/*": [
"app/*"
]
}
}
}

View File

@ -1,59 +0,0 @@
const webpack = require('webpack');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const path = require('path');
module.exports = {
entry: './src/main.ts',
resolve: {
extensions: ['.ts', '.js'],
alias: {
'@': path.resolve(__dirname, 'src/app/'),
}
},
module: {
rules: [
{
test: /\.ts$/,
use: ['ts-loader', 'angular2-template-loader']
},
{
test: /\.html$/,
use: 'html-loader'
},
{
test: /\.less$/,
use: ['style-loader', 'css-loader', 'less-loader']
},
// workaround for warning: System.import() is deprecated and will be removed soon. Use import() instead.
{
test: /[\/\\]@angular[\/\\].+\.js$/,
parser: { system: true }
}
]
},
plugins: [
new HtmlWebpackPlugin({ template: './src/index.html' }),
new webpack.DefinePlugin({
// global app config object
config: JSON.stringify({
apiUrl: 'http://localhost:4000'
})
}),
// workaround for warning: Critical dependency: the request of a dependency is an expression
new webpack.ContextReplacementPlugin(
/\@angular(\\|\/)core(\\|\/)fesm5/,
path.resolve(__dirname, 'src')
)
],
optimization: {
splitChunks: {
chunks: 'all',
},
runtimeChunk: true
},
devServer: {
historyApiFallback: true
}
}

View File

@ -1,31 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>pl.chal</groupId>
<artifactId>chal</artifactId>
<version>1.0</version>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-java</artifactId>
<version>3.0.1</version>
</dependency>
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-chrome-driver</artifactId>
<version>3.0.1</version>
</dependency>
</dependencies>
</project>

View File

@ -1,69 +0,0 @@
//Aby uruchomić należy pobrać kod z repozytorium, uruchomić mvn clean install, umieścić chromedriver w podanym katalogu i podać dane do logowania do usosa oraz swoje imie i nazwisko ponizej
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.support.ui.ExpectedCondition;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
import java.io.IOException;
import java.util.List;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
public class UsosTest {
private String testUrl;
private WebDriver driver;
@Test
public void testLogin() throws IOException, InterruptedException {
System.setProperty("webdriver.chrome.driver", "C:\\projects\\CHAL\\ui-test\\webdriver\\chromedriver.exe");
testUrl = "https://usosweb.amu.edu.pl";
driver = new ChromeDriver();
driver.manage().window().maximize();
driver.get(testUrl);
WebDriverWait wait = new WebDriverWait(driver, 5);
// Find login by attribute lang="READ_MORE_BTN"
List<WebElement> login = driver.findElements(By.xpath("//*[@id=\"casmenu\"]/table/tbody/tr/td[2]/a"));
wait.until(ExpectedConditions.visibilityOfElementLocated(By.xpath("//*[@id=\"casmenu\"]/table/tbody/tr/td[2]/a")));
//Click the selected button
login.get(0).click();
wait.until(ExpectedConditions.visibilityOfElementLocated(By.xpath("//*[@id=\"username\"]")));
List<WebElement> loginFirst = driver.findElements(By.xpath("//*[@id=\"username\"]"));
loginFirst.get(0).click();
loginFirst.get(0).sendKeys("96072910592");
List<WebElement> loginPassword = driver.findElements(By.xpath("//*[@id=\"password\"]"));
loginPassword.get(0).click();
loginPassword.get(0).sendKeys("haslotu");
List<WebElement> loginButton = driver.findElements(By.xpath("//*[@id=\"fm1\"]/div[1]/button[1]"));
loginButton.get(0).click();
wait.until(ExpectedConditions.visibilityOfElementLocated(By.xpath("//*[@id=\"casmenu\"]/table/tbody/tr/td[2]/b")));
List<WebElement> loggedUser = driver.findElements(By.xpath("//*[@id=\"casmenu\"]/table/tbody/tr/td[2]/b"));
assertEquals("Jakub Kowalczyk", loggedUser.get(0).getText());
}
@After
public void teardown() throws IOException {
driver.quit();
}
}

Binary file not shown.