Skip to content

Commit

Permalink
split up shared-register component into register and me-update orderc…
Browse files Browse the repository at this point in the history
  • Loading branch information
Crhistian Ramirez committed Nov 19, 2018
1 parent 4dd152b commit 83149f6
Show file tree
Hide file tree
Showing 20 changed files with 373 additions and 256 deletions.
2 changes: 1 addition & 1 deletion src/UI/Buyer/src/app/auth/auth-routing.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { RouterModule, Routes } from '@angular/router';
// auth components
import { LoginComponent } from '@app-buyer/auth/containers/login/login.component';
import { ForgotPasswordComponent } from '@app-buyer/auth/containers/forgot-password/forgot-password.component';
import { RegisterComponent } from '@app-buyer/shared';
import { RegisterComponent } from '@app-buyer/auth/containers/register/register.component';
import { ResetPasswordComponent } from '@app-buyer/auth/containers/reset-password/reset-password.component';

const routes: Routes = [
Expand Down
2 changes: 2 additions & 0 deletions src/UI/Buyer/src/app/auth/auth.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { SharedModule } from '@app-buyer/shared';

// components
import { LoginComponent } from '@app-buyer/auth/containers/login/login.component';
import { RegisterComponent } from '@app-buyer/auth/containers/register/register.component';
import { ForgotPasswordComponent } from '@app-buyer/auth/containers/forgot-password/forgot-password.component';
import { ResetPasswordComponent } from '@app-buyer/auth/containers/reset-password/reset-password.component';

Expand All @@ -14,6 +15,7 @@ import { AuthRoutingModule } from '@app-buyer/auth/auth-routing.module';
imports: [SharedModule, AuthRoutingModule],
declarations: [
LoginComponent,
RegisterComponent,
ForgotPasswordComponent,
ResetPasswordComponent,
],
Expand Down
Original file line number Diff line number Diff line change
@@ -1,25 +1,19 @@
<div *ngIf="!shouldAllowUpdate"
class="text-center mt-3">
<div class="text-center mt-3">
<p>Already have an account? <button type="button"
class="btn btn-link"
routerLink="/login">Login</button></p>
<h1 class="display-4">{{appConfig.appname}}</h1>
</div>
<div *ngIf="shouldAllowUpdate">
<h1 class="page-heading border-bottom pb-3">Account Details</h1>
</div>
<div class="row">
<div class="col-lg-6"
[ngClass]="{'mx-auto': !shouldAllowUpdate}"
[ngStyle]="{'max-width': !shouldAllowUpdate ? '350px' : ''}">
<h3 *ngIf="!shouldAllowUpdate"
class="text-center headline-text mb-3">Sign Up</h3>
<div class="col-lg-6 mx-auto"
style="max-width:400px">
<h3 class="text-center headline-text mb-3">Sign Up</h3>
<form (ngSubmit)="onSubmit()"
novalidate
[formGroup]="form"
name="RegisterForm">
<div class="form-group">
<label [ngClass]="{'sr-only': !shouldAllowUpdate}"
<label class="sr-only"
for="Username">Username</label>
<input type="text"
formControlName="Username"
Expand All @@ -32,7 +26,7 @@ <h1 class="page-heading border-bottom pb-3">Account Details</h1>
class="error-message">Username is required</span>
</div>
<div class="form-group">
<label [ngClass]="{'sr-only': !shouldAllowUpdate}"
<label class="sr-only"
for="FirstName">First Name</label>
<input type="text"
formControlName="FirstName"
Expand All @@ -46,7 +40,7 @@ <h1 class="page-heading border-bottom pb-3">Account Details</h1>
class="error-message">Name can only contain characters Aa-Zz 0-9 - ' .</span>
</div>
<div class="form-group">
<label [ngClass]="{'sr-only': !shouldAllowUpdate}"
<label class="sr-only"
for="LastName">Last Name</label>
<input type="text"
formControlName="LastName"
Expand All @@ -60,7 +54,7 @@ <h1 class="page-heading border-bottom pb-3">Account Details</h1>
class="error-message">Name can only contain characters Aa-Zz 0-9 - ' .</span>
</div>
<div class="form-group">
<label [ngClass]="{'sr-only': !shouldAllowUpdate}"
<label class="sr-only"
for="Email">Email</label>
<input type="email"
formControlName="Email"
Expand All @@ -72,7 +66,7 @@ <h1 class="page-heading border-bottom pb-3">Account Details</h1>
class="error-message">Please enter a valid email</span>
</div>
<div class="form-group">
<label [ngClass]="{'sr-only': !shouldAllowUpdate}"
<label class="sr-only"
for="Phone">Phone Number</label>
<input type="text"
formControlName="Phone"
Expand All @@ -83,9 +77,8 @@ <h1 class="page-heading border-bottom pb-3">Account Details</h1>
<span *ngIf="hasPatternError('Phone')"
class="error-message">Phone can only contain 20 numbers or "-" chars (no spaces)</span>
</div>
<div *ngIf="!shouldAllowUpdate"
class="form-group">
<label [ngClass]="{'sr-only': !shouldAllowUpdate}"
<div class="form-group">
<label class="sr-only"
for="Password">Password</label>
<input type="password"
formControlName="Password"
Expand All @@ -96,8 +89,7 @@ <h1 class="page-heading border-bottom pb-3">Account Details</h1>
<span *ngIf="hasRequiredError('Password')"
class="error-message">Password is required</span>
</div>
<div *ngIf="!shouldAllowUpdate"
class="form-group">
<div class="form-group">
<label class="sr-only"
for="ConfirmPassword">Confirm Password</label>
<input type="password"
Expand All @@ -111,28 +103,14 @@ <h1 class="page-heading border-bottom pb-3">Account Details</h1>
<span *ngIf="passwordMismatchError()"
class="error-message">Passwords must match</span>
</div>
<button type="button"
*ngIf="shouldAllowUpdate"
class="btn btn-outline-primary btn-block"
(click)="openChangePasswordModal()">Change
Password
</button>
<button type="submit"
class="btn btn-primary btn-lg btn-block mt-4">{{ shouldAllowUpdate ? 'Save Changes' : 'Register'
}}
class="btn btn-primary btn-lg btn-block mt-4">Register
</button>
</form>
<button *ngIf="!shouldAllowUpdate"
type="button"
<button type="button"
class="btn btn-link btn-block"
routerLink="/forgot-password">Forgot
Password
</button>
</div>
</div>

<!-- Change Password Modal Content -->
<shared-modal [id]="changePasswordModalId"
modalTitle="Change Password">
<shared-change-password-form (changePassword)="onChangePassword($event)"></shared-change-password-form>
</shared-modal>
</div>
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { RegisterComponent } from '@app-buyer/auth/containers/register/register.component';
import { ReactiveFormsModule } from '@angular/forms';
import { OcMeService, OcTokenService, MeUser } from '@ordercloud/angular-sdk';
import { CookieModule } from 'ngx-cookie';
import {
applicationConfiguration,
AppConfig,
} from '@app-buyer/config/app.config';
import { InjectionToken, NO_ERRORS_SCHEMA } from '@angular/core';
import { Router } from '@angular/router';
import { ToastrService } from 'ngx-toastr';
import { AppStateService, AppFormErrorService } from '@app-buyer/shared';
import { of, Subject } from 'rxjs';

describe('RegisterComponent', () => {
let component: RegisterComponent;
let fixture: ComponentFixture<RegisterComponent>;

const appStateService = { userSubject: new Subject<any>() };
const ocMeService = {
Register: jasmine.createSpy('Register').and.returnValue(of(null)),
};
const toastrService = { success: jasmine.createSpy('success') };
const tokenService = {
GetAccess: jasmine.createSpy('GetAccess').and.returnValue('mockToken'),
};
const router = { navigate: jasmine.createSpy('navigate') };
const formErrorService = {
hasRequiredError: jasmine.createSpy('hasRequiredError'),
hasInvalidEmailError: jasmine.createSpy('hasInvalidEmailError'),
hasPasswordMismatchError: jasmine.createSpy('hasPasswordMismatchError'),
hasStrongPasswordError: jasmine.createSpy('hasStrongPasswordError'),
displayFormErrors: jasmine.createSpy('displayFormErrors'),
hasPatternError: jasmine.createSpy('hasPatternError'),
};

beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [RegisterComponent],
imports: [ReactiveFormsModule, CookieModule.forRoot()],
providers: [
{ provide: AppFormErrorService, useValue: formErrorService },
{ provide: Router, useValue: router },
{ provide: OcTokenService, useValue: tokenService },
{ provide: OcMeService, useValue: ocMeService },
{ provide: AppStateService, useValue: appStateService },
{ provide: ToastrService, useValue: toastrService },
{
provide: applicationConfiguration,
useValue: new InjectionToken<AppConfig>('app.config'),
},
],
schemas: [NO_ERRORS_SCHEMA],
}).compileComponents();
}));

beforeEach(() => {
fixture = TestBed.createComponent(RegisterComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});

it('should create', () => {
expect(component).toBeTruthy();
});

describe('ngOnInit', () => {
beforeEach(() => {
spyOn(component as any, 'setForm');
});
it('should call setForm', () => {
component.ngOnInit();
expect(component['setForm']).toHaveBeenCalled();
});
});

describe('setForm', () => {
it('should initialize form', () => {
component['setForm']();
expect(component.form.value).toEqual({
Username: '',
FirstName: '',
LastName: '',
Email: '',
Phone: '',
Password: '',
ConfirmPassword: '',
});
});
});

describe('onSubmit', () => {
it('should call displayFormErrors if form is invalid', () => {
component.form.controls.FirstName.setValue('');
component['onSubmit']();
expect(formErrorService.displayFormErrors).toHaveBeenCalled();
});
it('should call meService.Register', () => {
component.form.controls.Username.setValue('crhistianr');
component.form.controls.FirstName.setValue('Crhistian');
component.form.controls.LastName.setValue('Ramirez');
component.form.controls.Email.setValue(
'crhistian-rawks@my-little-pony.com'
);
component.form.controls.Phone.setValue('555-555-5555');
component.form.controls.Password.setValue('easyguess123');
component.form.controls.ConfirmPassword.setValue('easyguess123');
component['onSubmit']();
const mockMe = <MeUser>component.form.value;
mockMe.Active = true;
expect(ocMeService.Register).toHaveBeenCalledWith('mockToken', mockMe);
});
it('should navigate to login', () => {
component['onSubmit']();
expect(router.navigate).toHaveBeenCalledWith(['/login']);
});
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
import { Component, OnInit, Inject, OnDestroy } from '@angular/core';
import { FormGroup, FormBuilder, Validators } from '@angular/forms';
import { Router } from '@angular/router';
import { ToastrService } from 'ngx-toastr';
import { OcMeService, OcTokenService, MeUser } from '@ordercloud/angular-sdk';
import {
applicationConfiguration,
AppConfig,
} from '@app-buyer/config/app.config';
import { AppFormErrorService } from '@app-buyer/shared/services/form-error/form-error.service';
import { AppMatchFieldsValidator } from '@app-buyer/shared/validators/match-fields/match-fields.validator';
import { RegexService } from '@app-buyer/shared/services/regex/regex.service';

@Component({
selector: 'auth-register',
templateUrl: './register.component.html',
styleUrls: ['./register.component.scss'],
})
export class RegisterComponent implements OnInit, OnDestroy {
form: FormGroup;
me: MeUser;
alive = true;

constructor(
private formBuilder: FormBuilder,
private formErrorService: AppFormErrorService,
private ocMeService: OcMeService,
private ocTokenService: OcTokenService,
private router: Router,
private toastrService: ToastrService,
private regexService: RegexService,
@Inject(applicationConfiguration) protected appConfig: AppConfig
) {}

ngOnInit() {
this.setForm();
}

private setForm() {
this.form = this.formBuilder.group(
{
Username: ['', Validators.required],
FirstName: [
'',
[
Validators.required,
Validators.pattern(this.regexService.HumanName),
],
],
LastName: [
'',
[
Validators.required,
Validators.pattern(this.regexService.HumanName),
],
],
Email: ['', [Validators.required, Validators.email]],
Phone: ['', Validators.pattern(this.regexService.Phone)],
Password: ['', [Validators.required, Validators.minLength(8)]],
ConfirmPassword: ['', [Validators.required, Validators.minLength(8)]],
},
{
validator: AppMatchFieldsValidator('Password', 'ConfirmPassword'),
}
);
}

onSubmit() {
if (this.form.status === 'INVALID') {
return this.formErrorService.displayFormErrors(this.form);
}

const me = <MeUser>this.form.value;
me.Active = true;

this.ocMeService
.Register(this.ocTokenService.GetAccess(), me)
.subscribe(() => {
this.toastrService.success('New User Created');
this.router.navigate(['/login']);
});
}

ngOnDestroy() {
this.alive = false;
}

// control display of error messages
protected hasRequiredError = (controlName: string): boolean =>
this.formErrorService.hasRequiredError(controlName, this.form);
protected hasEmailError = (): boolean =>
this.formErrorService.hasInvalidEmailError(this.form.get('Email'));
protected hasPatternError = (controlName: string) =>
this.formErrorService.hasPatternError(controlName, this.form);
protected passwordMismatchError = (): boolean =>
this.formErrorService.hasPasswordMismatchError(this.form);
}
2 changes: 1 addition & 1 deletion src/UI/Buyer/src/app/config/app.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { environment } from '../../environments/environment';
export const ocAppConfig: AppConfig = {
appname: 'OrderCloud',
clientID: environment.clientID,
anonymousShoppingEnabled: false,
anonymousShoppingEnabled: true,
premiumSearchEnabled: false,
middlewareUrl: environment.middlewareUrl,
scope: [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { MeUser } from '@ordercloud/angular-sdk';
import { ValidateStrongPassword } from '@app-buyer/shared/validators/strong-password/strong-password.validator';

@Component({
selector: 'shared-change-password-form',
selector: 'profile-change-password-form',
templateUrl: './change-password-form.component.html',
styleUrls: ['./change-password-form.component.scss'],
})
Expand Down
Loading

0 comments on commit 83149f6

Please sign in to comment.