diff --git a/client/src/app/core/containers/app.component.spec.ts b/client/src/app/core/containers/app.component.spec.ts
index ad205840c6623e5ecf5d50c8abb035939390e6f5..548bcf07d1f8fe03b82ea3d2ee1a1bd21076bd5b 100644
--- a/client/src/app/core/containers/app.component.spec.ts
+++ b/client/src/app/core/containers/app.component.spec.ts
@@ -7,7 +7,6 @@ import { provideMockStore, MockStore } from '@ngrx/store/testing';
 import { AppComponent } from './app.component';
 import { AppConfigService } from 'src/app/app-config.service';
 import * as authActions from 'src/app/auth/auth.actions';
-import * as attributeActions from '../../metamodel/actions/attribute.actions';
 import * as instanceActions from '../../metamodel/actions/instance.actions';
 
 describe('AppComponent', () => {
diff --git a/client/src/app/portal/components/instance-card.component.html b/client/src/app/portal/components/instance-card.component.html
index 85c5825eb2dcd9d7c2888f9c548fb3ed9a7db456..2916864f55780973f006196bb77f59c6c89c1eb7 100644
--- a/client/src/app/portal/components/instance-card.component.html
+++ b/client/src/app/portal/components/instance-card.component.html
@@ -4,7 +4,7 @@
         <p class="card-text">Some quick example text to build on the card title and make up the bulk of the card's content.</p>
     </div>
     <div class="card-footer bg-transparent text-right">
-        <a routerLink="/instance/{{instance.name}}" class="btn btn-outline-primary" title="Go to instance">
+        <a routerLink="/instance/{{ instance.name }}" class="btn btn-outline-primary" title="Go to instance">
             Go to instance
         </a>
     </div>
diff --git a/client/src/app/portal/components/instance-card.component.spec.ts b/client/src/app/portal/components/instance-card.component.spec.ts
new file mode 100644
index 0000000000000000000000000000000000000000..9ce3bf87334a972173dd70338bef17a4fb0fc202
--- /dev/null
+++ b/client/src/app/portal/components/instance-card.component.spec.ts
@@ -0,0 +1,22 @@
+import { TestBed, waitForAsync, ComponentFixture  } from '@angular/core/testing';
+import { RouterTestingModule } from '@angular/router/testing';
+
+import { InstanceCardComponent } from './instance-card.component';
+
+describe('InstanceCardComponent', () => {
+    let component: InstanceCardComponent;
+    let fixture: ComponentFixture<InstanceCardComponent>;
+
+    beforeEach(waitForAsync(() => {
+        TestBed.configureTestingModule({
+            imports: [RouterTestingModule],
+            declarations: [InstanceCardComponent]
+        }).compileComponents();
+        fixture = TestBed.createComponent(InstanceCardComponent);
+        component = fixture.componentInstance;
+    }));
+
+    it('should create the component', () => {
+        expect(component).toBeDefined();
+    });
+});
diff --git a/client/src/app/portal/components/instance-card.component.ts b/client/src/app/portal/components/instance-card.component.ts
index 405a808a5ab29f76cf4855b6fffc904c6cc3efad..c50e4b734d74a0e6c02d73430db6a8bedeb4af01 100644
--- a/client/src/app/portal/components/instance-card.component.ts
+++ b/client/src/app/portal/components/instance-card.component.ts
@@ -11,6 +11,10 @@ import { Component, Input, ChangeDetectionStrategy } from '@angular/core';
 
 import { Instance } from 'src/app/metamodel/models';
 
+/**
+ * @class
+ * @classdesc Instance card component.
+ */
 @Component({
     selector: 'app-instance-card',
     templateUrl: 'instance-card.component.html',
diff --git a/client/src/app/portal/containers/portal-home.component.spec.ts b/client/src/app/portal/containers/portal-home.component.spec.ts
index 6d707e36f09a66596196c426ec4fc632bcbf1ddd..e7e405cbf2d0ba90f1a60e9f8ee896b3f11ecc02 100644
--- a/client/src/app/portal/containers/portal-home.component.spec.ts
+++ b/client/src/app/portal/containers/portal-home.component.spec.ts
@@ -3,17 +3,18 @@ import { TestBed, waitForAsync, ComponentFixture  } from '@angular/core/testing'
 import { RouterTestingModule } from '@angular/router/testing';
 
 import { provideMockStore, MockStore } from '@ngrx/store/testing';
+import { of } from 'rxjs';
 
+import { PortalHomeComponent } from './portal-home.component';
 import { AppConfigService } from 'src/app/app-config.service';
 import { UserProfile } from 'src/app/auth/user-profile.model';
 import { Instance } from 'src/app/metamodel/models';
 import * as authActions from 'src/app/auth/auth.actions';
-import { PortalHomeComponent } from './portal-home.component';
 
 describe('PortalHomeComponent', () => {
     @Component({ selector: 'app-navbar', template: '' })
     class NavbarStubComponent {
-        @Input() links: {label: string, icon: string, routerLink: string}[];
+        @Input() links: { label: string, icon: string, routerLink: string }[];
         @Input() isAuthenticated: boolean;
         @Input() userProfile: UserProfile = null;
         @Input() baseHref: string;
@@ -28,13 +29,11 @@ describe('PortalHomeComponent', () => {
     let component: PortalHomeComponent;
     let fixture: ComponentFixture<PortalHomeComponent>;
     let store: MockStore;
-    let config: AppConfigService
+    let appConfigServiceStub = new AppConfigService();
 
     beforeEach(waitForAsync(() => {
         TestBed.configureTestingModule({
-            imports: [
-                RouterTestingModule
-            ],
+            imports: [RouterTestingModule],
             declarations: [
                 PortalHomeComponent,
                 NavbarStubComponent,
@@ -42,47 +41,81 @@ describe('PortalHomeComponent', () => {
             ],
             providers: [
                 provideMockStore({ }),
-                AppConfigService
+                { provide: AppConfigService, useValue: appConfigServiceStub }
             ]
         }).compileComponents();
         fixture = TestBed.createComponent(PortalHomeComponent);
         component = fixture.componentInstance;
         store = TestBed.inject(MockStore);
-        config = TestBed.inject(AppConfigService);
+        document.body.innerHTML = '<link id="favicon" href="">';
     }));
 
-    it('should create the portal home component', () => {
+    it('should create the component', () => {
         expect(component).toBeDefined();
     });
 
-    it('getBaseHref() should give base href config key value', () => {
-        config.baseHref = '/my-project';
+    it('should execute ngOnInit lifecycle and add admin link if no authentication', () => {
+        appConfigServiceStub.authenticationEnabled = false;
+        component.ngOnInit();
+        const expected = [
+            { label: 'Home', icon: 'fas fa-home', routerLink: '/portal' },
+            { label: 'Admin', icon: 'fas fa-tools', routerLink: '/admin' }
+        ];
+        expect(component.links).toEqual(expected);
+        expect(component.favIcon.href).toEqual('http://localhost/favicon.ico');
+    });
+
+    it('should execute ngOnInit lifecycle and add admin link depending on user rights', () => {
+        appConfigServiceStub.authenticationEnabled = true;
+        appConfigServiceStub.adminRole = 'admin';
+        component.userRoles = of([]);
+        component.ngOnInit();
+        expect(component.links).toEqual([{ label: 'Home', icon: 'fas fa-home', routerLink: '/portal' }]);
+        component.userRoles = of(['admin']);
+        component.ngOnInit();
+        const expected = [
+            { label: 'Home', icon: 'fas fa-home', routerLink: '/portal' },
+            { label: 'Admin', icon: 'fas fa-tools', routerLink: '/admin' }
+        ];
+        expect(component.links).toEqual(expected);
+
+    });
+
+    it('#getBaseHref() should return base href config key value', () => {
+        appConfigServiceStub.baseHref = '/my-project';
         expect(component.getBaseHref()).toBe('/my-project');
     });
 
-    it('authenticationEnabled() should give authentication enabled config key value', () => {
-        config.authenticationEnabled = true;
+    it('#authenticationEnabled() should return authentication enabled config key value', () => {
+        appConfigServiceStub.authenticationEnabled = true;
         expect(component.getAuthenticationEnabled()).toBeTruthy();
     });
 
-    it('login() should dispatch login action', () => {
+    it('#login() should dispatch login action', () => {
         const spy = jest.spyOn(store, 'dispatch');
         component.login();
         expect(spy).toHaveBeenCalledTimes(1);
         expect(spy).toHaveBeenCalledWith(authActions.login());
     });
 
-    it('logout() should dispatch logout action', () => {
+    it('#logout() should dispatch logout action', () => {
         const spy = jest.spyOn(store, 'dispatch');
         component.logout();
         expect(spy).toHaveBeenCalledTimes(1);
         expect(spy).toHaveBeenCalledWith(authActions.logout());
     });
 
-    it('openEditProfile() should dispatch open edit profile action', () => {
+    it('#openEditProfile() should dispatch open edit profile action', () => {
         const spy = jest.spyOn(store, 'dispatch');
         component.openEditProfile();
         expect(spy).toHaveBeenCalledTimes(1);
         expect(spy).toHaveBeenCalledWith(authActions.openEditProfile());
     });
+
+    it('should unsubscribe to user roles when component is destroyed', () => {
+        component.userRolesSubscription = of().subscribe();
+        const spy = jest.spyOn(component.userRolesSubscription, 'unsubscribe');
+        component.ngOnDestroy();
+        expect(spy).toHaveBeenCalledTimes(1);
+    });
 });
diff --git a/client/src/app/portal/containers/portal-home.component.ts b/client/src/app/portal/containers/portal-home.component.ts
index e64f8f617dc3ddf6a1b8acac4b709fb28c527a08..5a7e3ae9eb65d592850815589e008bffd20c4f9c 100644
--- a/client/src/app/portal/containers/portal-home.component.ts
+++ b/client/src/app/portal/containers/portal-home.component.ts
@@ -8,6 +8,7 @@
  */
 
 import { Component, OnInit, OnDestroy } from '@angular/core';
+
 import { Observable, Subscription } from 'rxjs';
 import { Store } from '@ngrx/store';
 
@@ -18,26 +19,24 @@ import * as authSelector from 'src/app/auth/auth.selector';
 import * as instanceSelector from 'src/app/metamodel/selectors/instance.selector';
 import { AppConfigService } from 'src/app/app-config.service';
 
-@Component({
-    selector: 'app-portal-home',
-    templateUrl: 'portal-home.component.html'
-})
 /**
  * @class
  * @classdesc Portal home container.
  *
  * @implements OnInit
+ * @implements OnDestroy
  */
+@Component({
+    selector: 'app-portal-home',
+    templateUrl: 'portal-home.component.html'
+})
 export class PortalHomeComponent implements OnInit, OnDestroy {
     public favIcon: HTMLLinkElement = document.querySelector('#favicon');
-    public links = [
-        { label: 'Home', icon: 'fas fa-home', routerLink: '/portal' }
-    ];
+    public links = [{ label: 'Home', icon: 'fas fa-home', routerLink: '/portal' }];
     public isAuthenticated: Observable<boolean>;
     public userProfile: Observable<UserProfile>;
     public userRoles: Observable<string[]>;
     public instanceList: Observable<Instance[]>;
-
     public userRolesSubscription: Subscription;
 
     constructor(private store: Store<{ }>, private config: AppConfigService) {
@@ -61,27 +60,49 @@ export class PortalHomeComponent implements OnInit, OnDestroy {
         }
     }
 
-    getBaseHref() {
+    /**
+     * Returns application base href.
+     *
+     * @return string
+     */
+    getBaseHref(): string {
         return this.config.baseHref;
     }
 
-    getAuthenticationEnabled() {
+    /**
+     * Checks if authentication is enabled.
+     *
+     * @return boolean
+     */
+    getAuthenticationEnabled(): boolean {
         return this.config.authenticationEnabled;
     }
-    
+
+    /**
+     * Dispatches action to log in.
+     */
     login(): void {
         this.store.dispatch(authActions.login());
     }
 
+    /**
+     * Dispatches action to log out.
+     */
     logout(): void {
         this.store.dispatch(authActions.logout());
     }
 
+    /**
+     * Dispatches action to open profile editor.
+     */
     openEditProfile(): void {
         this.store.dispatch(authActions.openEditProfile());
     }
 
-    ngOnDestroy() {
+    /**
+     * Unsubscribes to user roles when component is destroyed.
+     */
+    ngOnDestroy(): void {
         if (this.userRolesSubscription) this.userRolesSubscription.unsubscribe();
     }
 }
diff --git a/client/src/app/portal/portal-routing.module.ts b/client/src/app/portal/portal-routing.module.ts
index 3874af69e7b07bd30358857ec40196b68681f2f5..dc43b6ed26cc553539c67fcac8ab8758e647d235 100644
--- a/client/src/app/portal/portal-routing.module.ts
+++ b/client/src/app/portal/portal-routing.module.ts
@@ -17,6 +17,10 @@ const routes: Routes = [
     { path: 'home', component: PortalHomeComponent }
 ];
 
+/**
+ * @class
+ * @classdesc Portal routing module.
+ */
 @NgModule({
     imports: [RouterModule.forChild(routes)],
     exports: [RouterModule]
diff --git a/client/src/app/portal/portal.module.ts b/client/src/app/portal/portal.module.ts
index 09687afe56a281b70254d7ab38b2365bb1b7c755..90d8e5a01cc4593a5af19e01c7025e33bf021ad6 100644
--- a/client/src/app/portal/portal.module.ts
+++ b/client/src/app/portal/portal.module.ts
@@ -13,6 +13,10 @@ import { SharedModule } from 'src/app/shared/shared.module';
 import { PortalRoutingModule, routedComponents } from './portal-routing.module';
 import { dummiesComponents } from './components';
 
+/**
+ * @class
+ * @classdesc Portal module.
+ */
 @NgModule({
     imports: [
         SharedModule,