Skip to content

Commit

Permalink
#3 Increase test coverage
Browse files Browse the repository at this point in the history
* #3 Cover PasswordGeneratorService
* #3 Cover StorageApiService
* #3 Cover EditFormComponent
  • Loading branch information
maprox authored Jun 5, 2018
1 parent 9f8471e commit a643326
Show file tree
Hide file tree
Showing 21 changed files with 795 additions and 33 deletions.
28 changes: 14 additions & 14 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,15 @@
"private": true,
"dependencies": {
"@angular-devkit/build-angular": "^0.6.1",
"@angular/animations": "6.0.0",
"@angular/common": "6.0.0",
"@angular/compiler": "6.0.0",
"@angular/core": "6.0.0",
"@angular/forms": "6.0.0",
"@angular/http": "6.0.0",
"@angular/platform-browser": "6.0.0",
"@angular/platform-browser-dynamic": "6.0.0",
"@angular/router": "6.0.0",
"@angular/animations": "6.0.2",
"@angular/common": "6.0.2",
"@angular/compiler": "6.0.2",
"@angular/core": "6.0.2",
"@angular/forms": "6.0.2",
"@angular/http": "6.0.2",
"@angular/platform-browser": "6.0.2",
"@angular/platform-browser-dynamic": "6.0.2",
"@angular/router": "6.0.2",
"@types/crypto-js": "^3.1.39",
"@types/jasmine": "^2.8.7",
"bootstrap": "^3.3.7",
Expand All @@ -37,9 +37,9 @@
"zone.js": "^0.8.26"
},
"devDependencies": {
"@angular/cli": "6.0.1",
"@angular/compiler-cli": "6.0.0",
"@angular/language-service": "6.0.0",
"@angular/cli": "6.0.3",
"@angular/compiler-cli": "6.0.2",
"@angular/language-service": "6.0.2",
"@types/crypto-js": "^3.1.37",
"@types/jasmine": "~2.8.2",
"@types/jasminewd2": "~2.0.2",
Expand All @@ -54,10 +54,10 @@
"karma-jasmine": "~1.1.0",
"karma-jasmine-html-reporter": "^0.2.2",
"karma-phantomjs-launcher": "^1.0.4",
"phantomjs": "^2.1.7",
"phantomjs-prebuilt": "^2.1.7",
"protractor": "~5.2.0",
"ts-node": "~3.3.0",
"tslint": "~5.8.0",
"typescript": "2.7.2"
}
}
}
2 changes: 2 additions & 0 deletions src/app/auth/auth.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { AuthRoutingModule } from './auth-routing.module';
import { AuthGuard } from './auth.guard';
import { AuthInterceptor } from './auth.interceptor';
import { AuthService } from './auth.service';
import { ForkMeComponent } from '../fork-me';
import { LoginComponent, RegexpErrorComponent } from './login';
import { LogoutComponent } from './logout';

Expand All @@ -27,6 +28,7 @@ import { LogoutComponent } from './logout';
}
],
declarations: [
ForkMeComponent,
LoginComponent,
LogoutComponent,
RegexpErrorComponent
Expand Down
1 change: 1 addition & 0 deletions src/app/auth/auth.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ export class AuthService {
logOut() {
this.encrypting.setUser(null);
this.session = null;
sessionStorage.removeItem('session');
this.subject.next();
}

Expand Down
1 change: 1 addition & 0 deletions src/app/auth/login/login.component.html
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
<app-fork-me url="https://github.com/maprox/keyholder-angular"></app-fork-me>
<div class="container">
<div class="row">
<div class="col-md-8 col-md-offset-2">
Expand Down
7 changes: 7 additions & 0 deletions src/app/auth/login/login.component.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,12 @@ describe('LoginComponent', () => {

@Component({ template: '' }) class DummyComponent {}

@Component({
selector: 'app-fork-me',
template: '<div>Fake fork me component</div>'
})
class FakeForkMeComponent {}

beforeEach(async(() => {
authSubject = new Subject<Object>();
authServiceStub = {
Expand All @@ -70,6 +76,7 @@ describe('LoginComponent', () => {
])
],
declarations: [
FakeForkMeComponent,
LoginComponent,
DummyComponent,
RegexpErrorComponent
Expand Down
32 changes: 32 additions & 0 deletions src/app/fork-me/fork-me.component.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<a [href]="url"
class="github-corner"
aria-label="View source on Github">
<svg width="80"
height="80"
viewBox="0 0 250 250"
style="
fill:#70B7FD;
color:#fff;
position: absolute;
top: 0;
border: 0;
right: 0;"
aria-hidden="true">
<path d="M0,0 L115,115 L130,115 L142,142 L250,250 L250,0 Z"></path>
<path d="M128.3,109.0 C113.8,99.7 119.0,89.6 119.0,89.6 C122.0,82.7 120.5,78.6 120.5,
78.6 C119.2,72.0 123.4,76.3 123.4,76.3 C127.3,80.9 125.5,87.3 125.5,87.3 C122.9,
97.6 130.6,101.9 134.4,103.2"
fill="currentColor"
style="transform-origin: 130px 106px;"
class="octo-arm"></path>
<path d="M115.0,115.0 C114.9,115.1 118.7,116.5 119.8,115.4 L133.7,101.6 C136.9,
99.2 139.9,98.4 142.2,98.6 C133.8,88.0 127.5,74.4 143.8,58.0 C148.5,53.4 154.0,
51.2 159.7,51.0 C160.3,49.4 163.2,43.6 171.4,40.1 C171.4,40.1 176.1,42.5 178.8,
56.2 C183.1,58.6 187.2,61.8 190.9,65.4 C194.5,69.0 197.7,73.2 200.1,77.6 C213.8,
80.2 216.3,84.9 216.3,84.9 C212.7,93.1 206.9,96.0 205.4,96.6 C205.1,102.4 203.0,
107.8 198.3,112.5 C181.9,128.9 168.3,122.5 157.7,114.1 C157.9,116.9 156.7,
120.9 152.7,124.9 L141.0,136.5 C139.8,137.7 141.6,141.9 141.8,141.8 Z"
fill="currentColor"
class="octo-body"></path>
</svg>
</a>
24 changes: 24 additions & 0 deletions src/app/fork-me/fork-me.component.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
.github-corner:hover .octo-arm {
animation: octocat-wave 560ms ease-in-out;
}

@keyframes octocat-wave {
0%, 100% {
transform: rotate(0);
}
20%, 60% {
transform: rotate(-25deg);
}
40%, 80% {
transform: rotate(10deg);
}
}

@media (max-width: 500px) {
.github-corner:hover .octo-arm {
animation: none;
}
.github-corner .octo-arm {
animation: octocat-wave 560ms ease-in-out;
}
}
25 changes: 25 additions & 0 deletions src/app/fork-me/fork-me.component.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { async, ComponentFixture, TestBed } from '@angular/core/testing';

import { ForkMeComponent } from './fork-me.component';

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

beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ ForkMeComponent ]
})
.compileComponents();
}));

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

it('should create', () => {
expect(component).toBeTruthy();
});
});
11 changes: 11 additions & 0 deletions src/app/fork-me/fork-me.component.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { Component, Input } from '@angular/core';

@Component({
selector: 'app-fork-me',
templateUrl: './fork-me.component.html',
styleUrls: ['./fork-me.component.scss']
})
export class ForkMeComponent {
@Input() public url;
constructor() { }
}
1 change: 1 addition & 0 deletions src/app/fork-me/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './fork-me.component';
4 changes: 0 additions & 4 deletions src/app/navigation/navigation.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,6 @@
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="#">
<i class="fa fa-user-secret fa-lg"></i>&nbsp;
Key Holder
</a>
</div><!-- Collect the nav links, forms, and other content for toggling -->
<div class="collapse navbar-collapse" id="navbar">
<ul class="nav navbar-nav">
Expand Down
68 changes: 61 additions & 7 deletions src/app/password-generator/password-generator.service.spec.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,69 @@
import { TestBed, inject } from '@angular/core/testing';

import { Options } from './model';
import { PasswordGeneratorService } from './password-generator.service';

describe('PasswordGeneratorService', () => {
beforeEach(() => {
TestBed.configureTestingModule({
providers: [PasswordGeneratorService]
let service: PasswordGeneratorService;
beforeEach(() => {
TestBed.configureTestingModule({
providers: [PasswordGeneratorService]
});
});
});

it('should be created', inject([PasswordGeneratorService], (service: PasswordGeneratorService) => {
expect(service).toBeTruthy();
}));
beforeEach(inject([PasswordGeneratorService], (_service: PasswordGeneratorService) => {
service = _service;
}));

it('should be created', () => {
expect(service).toBeTruthy();
});

it('should generate passwords with default options', () => {
const options = new Options();
expect(options.length).toEqual(20);
expect(service.generate().length).toEqual(options.length);
});

it('should raise error with wrong options', () => {
const options = new Options(10, false, false, false, false);
expect(options.length).toEqual(10);
const expectedError = new Error('Invalid options for the password generator');
expect(() => service.generate(options)).toThrow(expectedError);
});

it('should raise error when length is 0', () => {
const options = new Options(0);
expect(options.length).toEqual(0);
const expectedError = new Error('Invalid options for the password generator');
expect(() => service.generate(options)).toThrow(expectedError);
});

it('should generate numeric passwords', () => {
const options = new Options(10, true, false, false, false);
const secret = service.generate(options);
expect(secret.length).toEqual(options.length);
expect((/^\d+$/).test(secret)).toBeTruthy();
});

it('should generate symbols passwords', () => {
const options = new Options(20, false, true, false, false);
const secret = service.generate(options);
expect(secret.length).toEqual(options.length);
expect((/^[\D\W]+$/).test(secret)).toBeTruthy();
});

it('should generate lowercase passwords', () => {
const options = new Options(20, false, false, true, false);
const secret = service.generate(options);
expect(secret.length).toEqual(options.length);
expect((/^[a-z]+$/).test(secret)).toBeTruthy();
});

it('should generate uppercase passwords', () => {
const options = new Options(20, false, false, false, true);
const secret = service.generate(options);
expect(secret.length).toEqual(options.length);
expect((/^[A-Z]+$/).test(secret)).toBeTruthy();
});
});
2 changes: 1 addition & 1 deletion src/app/password-generator/password-generator.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ export class PasswordGeneratorService {

// Generate character pool
const availableCharacters = this.getAvailableCharacters(options);
if (!availableCharacters) {
if (!availableCharacters || (options.length <= 0)) {
throw new Error('Invalid options for the password generator');
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { FormsModule } from '@angular/forms';
import { Subject } from 'rxjs/index';

import { Folder } from '../../model';
import { StorageService } from '../../storage.service';
import { EditFormFolderComponent } from './edit-form-folder.component';
import { EditFormFolderService } from './edit-form-folder.service';

describe('EditFormFolderComponent', () => {
let component: EditFormFolderComponent,
fixture: ComponentFixture<EditFormFolderComponent>,
storageCurrent: Folder,
storageServiceMock,
editEventSubject,
editFormFolderService;

beforeEach(async(() => {
storageCurrent = new Folder('current');
storageServiceMock = {
getCurrent: jasmine.createSpy().and.returnValue(storageCurrent),
openFolder: jasmine.createSpy(),
save: jasmine.createSpy()
};
editEventSubject = new Subject<Object>();
editFormFolderService = {
getEditEvent: jasmine.createSpy().and.returnValue(editEventSubject)
};

TestBed.configureTestingModule({
imports: [
FormsModule
],
declarations: [
EditFormFolderComponent
],
providers: [
{
provide: StorageService,
useValue: storageServiceMock
},
{
provide: EditFormFolderService,
useValue: editFormFolderService
}
]
}).compileComponents();
}));

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

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

it('should save in edit mode', () => {
expect(component.isEditMode()).toBeFalsy();
expect(component.isActive).toBeFalsy();

editEventSubject.next(new Folder('test'));

expect(component.isEditMode()).toBeTruthy();
expect(component.isActive).toBeTruthy();

component.itemName = 'hello virtual world!';
component.submit();

expect(component.itemSource.getName()).toEqual('hello virtual world!');
expect(storageServiceMock.save).toHaveBeenCalled();
expect(component.isActive).toBeFalsy();
});

it('should add in create mode', () => {
expect(component.isEditMode()).toBeFalsy();
expect(component.isActive).toBeFalsy();

editEventSubject.next();

expect(component.isEditMode()).toBeFalsy();
expect(component.isActive).toBeTruthy();

const msg = 'hello virtual world!';
component.itemName = msg;
component.submit();

expect(component.itemSource).toBeUndefined();
expect(storageServiceMock.getCurrent).toHaveBeenCalled();
expect(storageServiceMock.save).toHaveBeenCalled();
expect(storageServiceMock.openFolder).toHaveBeenCalled();
expect(storageCurrent.getFolderByName(msg)).toEqual(new Folder(msg));
expect(component.isActive).toBeFalsy();
});
});
Loading

0 comments on commit a643326

Please sign in to comment.