Skip to content

Commit

Permalink
login failure
Browse files Browse the repository at this point in the history
  • Loading branch information
antonborisoff committed Feb 22, 2024
1 parent 49e27a4 commit ebabebb
Show file tree
Hide file tree
Showing 8 changed files with 121 additions and 9 deletions.
3 changes: 2 additions & 1 deletion src/app/components/login/i18n/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,6 @@
"LOGIN_BUTTON_LABEL": "Log in",
"VALIDATION_ERRORS": {
"EMPTY_VALUE": "Please, provide non-empty value"
}
},
"INVALID_CREDS": "Login or password are incorrect"
}
3 changes: 2 additions & 1 deletion src/app/components/login/i18n/ru.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,6 @@
"LOGIN_BUTTON_LABEL": "Войти",
"VALIDATION_ERRORS": {
"EMPTY_VALUE": "Пожалуйста, укажите непустое значение"
}
},
"INVALID_CREDS": "Неверный логин или пароль"
}
8 changes: 6 additions & 2 deletions src/app/components/login/login.component.html
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<div class="componentBorder">
<form [formGroup]="loginForm">
<form [formGroup]="loginForm" (ngSubmit)="onLogin()">
<div>
<input data-id="loginInput"
placeholder="{{'login.LOGIN_PLACEHOLDER' | transloco}}"
Expand All @@ -21,7 +21,11 @@
}
}
</div>
@if(incorrectLoginOrPassword) {
<div data-id="incorrectCreds">{{'login.INVALID_CREDS' | transloco}}</div>
}
<button data-id="loginButton"
[disabled]="loginForm.invalid">{{'login.LOGIN_BUTTON_LABEL' | transloco}}</button>
[disabled]="loginForm.invalid"
type="submit">{{'login.LOGIN_BUTTON_LABEL' | transloco}}</button>
</form>
</div>
31 changes: 29 additions & 2 deletions src/app/components/login/login.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,12 @@ import {
import {
requiredAfterTrimValidator
} from '../../validators'
import {
AuthService
} from '../../services/auth.service'
import {
HttpErrorResponse
} from '@angular/common/http'

const COMPONENT_TRANSLOCO_SCOPE = 'login'
@Component({
Expand All @@ -39,8 +45,12 @@ export class LoginComponent {
}

public loginForm
public constructor(private fb: FormBuilder) {
this.loginForm = this.fb.group({
public incorrectLoginOrPassword = false
public constructor(
private fb: FormBuilder,
private auth$: AuthService
) {
this.loginForm = this.fb.nonNullable.group({
login: [
'',
[requiredAfterTrimValidator()]
Expand All @@ -53,4 +63,21 @@ export class LoginComponent {
updateOn: 'blur'
})
}

public onLogin(): void {
this.incorrectLoginOrPassword = false
this.auth$.login(this.loginForm.controls.login.value, this.loginForm.controls.password.value).subscribe({
next: () => {
// redirect to home
},
error: (error: HttpErrorResponse) => {
if (error.status === 403) {
this.incorrectLoginOrPassword = true
}
else {
// notify about the error
}
}
})
}
}
9 changes: 7 additions & 2 deletions src/app/components/login/test/login.component.harness.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ export class LoginHarness extends ComponentHarness {
return await this.locatorFor(`input[data-id="${id}"]`)()
}

private async getButton(id: string): Promise<TestElement> {
return await this.locatorFor(`button[data-id="${id}"]`)()
private async getButton(id: string, ignoreDisabled: boolean = true): Promise<TestElement> {
return await this.locatorFor(`button[data-id="${id}"]${ignoreDisabled ? '' : ':not([disabled])'}`)()
}

private async getDiv(id: string, optional: boolean = false): Promise<TestElement | null> {
Expand All @@ -32,6 +32,11 @@ export class LoginHarness extends ComponentHarness {
}
}

public async clickButton(id: string): Promise<void> {
const button = await this.getButton(id, false)
await button.click()
}

public async buttonEnabled(id: string): Promise<boolean> {
const button = await this.getButton(id)
return !(await button.getProperty('disabled'))
Expand Down
37 changes: 36 additions & 1 deletion src/app/components/login/test/login.component.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,16 +15,42 @@ import {
import {
LoginHarness
} from './login.component.harness'
import {
AuthService
} from '../../../services/auth.service'
import {
of,
throwError
} from 'rxjs'
import {
HttpErrorResponse
} from '@angular/common/http'

describe('LoginComponent', () => {
let loginHarness: LoginHarness
const INVALID_LOGIN = 'invalid_login'

beforeEach(async () => {
const authServiceMock = jasmine.createSpyObj<AuthService>('authService', ['login'])
authServiceMock.login.and.callFake((login: string) => {
if (login === INVALID_LOGIN) {
return throwError(() => new HttpErrorResponse({
status: 403
}))
}
else {
return of()
}
})
await TestBed.configureTestingModule({
imports: [
LoginComponent,
getTranslocoTestingModule(LoginComponent, en)
]
],
providers: [{
provide: AuthService,
useValue: authServiceMock
}]
}).compileComponents()

const fixture = TestBed.createComponent(LoginComponent)
Expand Down Expand Up @@ -94,4 +120,13 @@ describe('LoginComponent', () => {
await loginHarness.enterInputValue('passwordInput', ' ')
expect(await loginHarness.controlPresent('passwordErrorEmpty')).toBe(false)
})

it('should display error message in case of invalid credentials', async () => {
expect(await loginHarness.controlPresent('incorrectCreds')).toBe(false)

await loginHarness.enterInputValue('loginInput', INVALID_LOGIN)
await loginHarness.enterInputValue('passwordInput', 'my_password')
await loginHarness.clickButton('loginButton')
expect(await loginHarness.controlPresent('incorrectCreds')).toBe(true)
})
})
20 changes: 20 additions & 0 deletions src/app/services/auth.service.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import {
TestBed
} from '@angular/core/testing'

import {
AuthService
} from './auth.service'

describe('AuthService', () => {
let service: AuthService

beforeEach(() => {
TestBed.configureTestingModule({})
service = TestBed.inject(AuthService)
})

it('should be created', () => {
expect(service).toBeTruthy()
})
})
19 changes: 19 additions & 0 deletions src/app/services/auth.service.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import {
Injectable
} from '@angular/core'
import {
Observable,
of
} from 'rxjs'

@Injectable({
providedIn: 'root'
})
export class AuthService {
public constructor() { }

public login(login: string, password: string): Observable<void> {
console.log(login + ' ' + password)
return of()
}
}

0 comments on commit ebabebb

Please sign in to comment.