Skip to content

Commit

Permalink
Merged in feature/SHIBUI-475 (pull request #68)
Browse files Browse the repository at this point in the history
SHIBUI-475: Copy Provider

Approved-by: Shibui Jenkins <shibui.jenkins@gmail.com>
Approved-by: Ryan Mathis <rmathis@unicon.net>
  • Loading branch information
rmathis committed May 10, 2018
1 parent 26a0933 commit f550f0a
Show file tree
Hide file tree
Showing 41 changed files with 1,282 additions and 122 deletions.
2 changes: 1 addition & 1 deletion ui/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

51 changes: 44 additions & 7 deletions ui/src/app/app.component.spec.ts
Original file line number Diff line number Diff line change
@@ -1,41 +1,78 @@
import { TestBed, async } from '@angular/core/testing';
import { Component, ViewChild } from '@angular/core';
import { TestBed, async, ComponentFixture } from '@angular/core/testing';
import { RouterTestingModule } from '@angular/router/testing';
import { StoreModule, Store, combineReducers } from '@ngrx/store';
import { AppComponent } from './app.component';

import { User } from './core/model/user';
import * as fromRoot from './core/reducer';
import * as fromVersion from './core/reducer/version.reducer';
import { NotificationModule } from './notification/notification.module';
import { NgbDropdownModule } from '@ng-bootstrap/ng-bootstrap';

@Component({
template: `
<app-root></app-root>
`
})
class TestHostComponent {
@ViewChild(AppComponent)
public componentUnderTest: AppComponent;
}

describe('AppComponent', () => {

let fixture: ComponentFixture<TestHostComponent>;
let instance: TestHostComponent;
let app: AppComponent;
let store: Store<fromRoot.State>;

beforeEach(async(() => {
TestBed.configureTestingModule({
imports: [
NgbDropdownModule.forRoot(),
RouterTestingModule,
StoreModule.forRoot({}),
StoreModule.forRoot({
core: combineReducers(fromRoot.reducers)
}),
NotificationModule
],
declarations: [
AppComponent
AppComponent,
TestHostComponent
],
}).compileComponents();

store = TestBed.get(Store);
spyOn(store, 'dispatch');

fixture = TestBed.createComponent(TestHostComponent);
instance = fixture.componentInstance;
app = instance.componentUnderTest;
fixture.detectChanges();
}));

it('should create the app', async(() => {
const fixture = TestBed.createComponent(AppComponent);
const app = fixture.debugElement.componentInstance;
expect(app).toBeTruthy();
expect(store.dispatch).toHaveBeenCalledTimes(4);
}));

it(`should have as title 'Shib-UI'`, async(() => {
const fixture = TestBed.createComponent(AppComponent);
const app = fixture.debugElement.componentInstance;
expect(app.title).toEqual('Shib UI');
}));

describe('version format', () => {
it('should return a formatted string', () => {
expect(app.formatter({
build: {
version: 'foo'
},
git: {
commit: {
id: 'bar'
}
}
})).toEqual('foo-bar');
});
});
});
4 changes: 3 additions & 1 deletion ui/src/app/app.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,11 @@ export class AppComponent implements OnInit {
formatted$: Observable<string>;
today = new Date();

formatter = v => v && v.build ? `${v.build.version}-${v.git.commit.id}` : '';

constructor(private store: Store<fromRoot.State>) {
this.version$ = this.store.select(fromRoot.getVersionInfo);
this.formatted$ = this.version$.map(v => v && v.build ? `${v.build.version}-${v.git.commit.id}` : '');
this.formatted$ = this.version$.map(this.formatter);
}

ngOnInit(): void {
Expand Down
2 changes: 1 addition & 1 deletion ui/src/app/domain/model/mdui.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,4 @@ export interface MDUI {
logoHeight?: number;
logoWidth?: number;
description?: string;
}
}
43 changes: 43 additions & 0 deletions ui/src/app/domain/reducer/filter-collection.reducer.spec.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,14 @@
import { reducer } from './filter-collection.reducer';
import * as fromFilter from './filter-collection.reducer';
import * as actions from '../action/filter-collection.action';
import {
FilterCollectionActionsUnion,
FilterCollectionActionTypes,
LoadFilterSuccess,
UpdateFilterSuccess,
SelectFilter
} from '../action/filter-collection.action';
import { Filter } from '../entity/filter';

const snapshot: fromFilter.FilterCollectionState = {
ids: [],
Expand All @@ -17,4 +25,39 @@ describe('Filter Reducer', () => {
expect(result).toEqual(snapshot);
});
});

describe(`${FilterCollectionActionTypes.SELECT}`, () => {
it('should set the selected id in the store', () => {
const selectedFilterId = 'foo';
const action = new SelectFilter(selectedFilterId);
const result = reducer(snapshot, action);
expect(result).toEqual({...snapshot, selectedFilterId});
});
});

describe(`${FilterCollectionActionTypes.LOAD_FILTER_SUCCESS}`, () => {
it('should add the loaded filters to the collection', () => {
spyOn(fromFilter.adapter, 'addMany').and.callThrough();
const filters = [
new Filter({ id: 'foo', createdDate: new Date().toLocaleDateString() }),
new Filter({ id: 'bar', createdDate: new Date().toLocaleDateString() })
];
const action = new LoadFilterSuccess(filters);
const result = reducer(snapshot, action);
expect(fromFilter.adapter.addMany).toHaveBeenCalled();
});
});

describe(`${FilterCollectionActionTypes.UPDATE_FILTER_SUCCESS}`, () => {
it('should add the loaded filters to the collection', () => {
spyOn(fromFilter.adapter, 'updateOne').and.callThrough();
const update = {
id: 'foo',
changes: new Filter({ id: 'foo', filterName: 'bar', createdDate: new Date().toLocaleDateString() }),
};
const action = new UpdateFilterSuccess(update);
const result = reducer(snapshot, action);
expect(fromFilter.adapter.updateOne).toHaveBeenCalled();
});
});
});
3 changes: 0 additions & 3 deletions ui/src/app/domain/service/entity-descriptor.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,6 @@ export class EntityDescriptorService {
}

save(provider: MetadataProvider): Observable<MetadataProvider> {
if (!environment.production) {
// console.log(JSON.stringify(provider));
}
return this.http.post<MetadataProvider>(`${this.base}${this.endpoint}`, provider);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
<input id="filterName" type="text" class="form-control" placeholder="" formControlName="filterName" />
<ng-container *ngIf="form.get('filterName').touched && form.get('filterName').invalid">
<small class="form-text text-danger" *ngIf="form.get('filterName').hasError('required')">
<ng-container i18n="@@message--service-provider-name-required">Filter Name is required</ng-container>
<ng-container i18n="@@message--filter-name-required">Filter Name is required</ng-container>
</small>
</ng-container>
</div>
Expand All @@ -56,7 +56,7 @@
aria-label="Information icon - press spacebar to read additional information for this form field"></i>
</span>
</div>
<label for="entityId" class="sr-only">Search Entity ID</label>
<label for="entityId" class="sr-only" i18n="@@label--search-entity-id">Search Entity ID</label>
<div class="row">
<div class="col-9">
<auto-complete id="entityId"
Expand All @@ -69,7 +69,7 @@
[processing]="(processing$ | async)"
(more)="onViewMore($event)">
</auto-complete>
<small class="form-text text-muted" i18n="@@label--min-4-chars">
<small class="form-text text-muted" i18n="@@label--min-chars">
Minimum 4 characters.
</small>
<ng-container *ngIf="form.get('entityId').touched && form.get('entityId').invalid">
Expand Down
97 changes: 97 additions & 0 deletions ui/src/app/metadata-filter/reducer/filter.reducer.spec.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,29 @@
import { reducer } from './filter.reducer';
import * as fromFilter from './filter.reducer';
import * as actions from '../action/filter.action';
import * as searchActions from '../action/search.action';
import {
SelectId,
LoadEntityPreviewSuccess,
UpdateFilterChanges,
CancelCreateFilter
} from '../action/filter.action';

import {
ClearSearch
} from '../action/search.action';

import {
FilterCollectionActionsUnion,
FilterCollectionActionTypes,
AddFilterRequest,
UpdateFilterRequest,
AddFilterSuccess,
UpdateFilterSuccess
} from '../../domain/action/filter-collection.action';
import { MDUI } from '../../domain/model/mdui';
import { MetadataFilter } from '../../domain/domain.type';
import { Filter } from '../../domain/entity/filter';

const snapshot: fromFilter.FilterState = {
selected: null,
Expand All @@ -9,6 +32,16 @@ const snapshot: fromFilter.FilterState = {
saving: false
};

const mdui: MDUI = {
displayName: 'foo',
informationUrl: 'bar',
privacyStatementUrl: 'baz',
logoUrl: '',
logoHeight: 100,
logoWidth: 100,
description: '',
};

describe('Filter Reducer', () => {
describe('undefined action', () => {
it('should return the default state', () => {
Expand All @@ -17,4 +50,68 @@ describe('Filter Reducer', () => {
expect(result).toEqual(snapshot);
});
});

describe(`${actions.SELECT_ID} action`, () => {
it('should set selected property to the provided payload', () => {
const id = 'foo';
const result = reducer(snapshot, new actions.SelectId(id));
expect(result.selected).toBe(id);
});
});

describe(`${actions.LOAD_ENTITY_PREVIEW_SUCCESS} action`, () => {
it('should set preview property to the provided payload', () => {
let sampleMdui = { ...mdui };
const result = reducer(snapshot, new actions.LoadEntityPreviewSuccess(sampleMdui));
expect(result.preview).toEqual(sampleMdui);
});
});

describe(`${actions.UPDATE_FILTER} action`, () => {
it('should update the state of changes', () => {
const changes = { filterEnabled: false };
const current = { ...snapshot, changes: { filterEnabled: true } as MetadataFilter };
const result = reducer(current, new actions.UpdateFilterChanges(changes));
expect(result.changes.filterEnabled).toBe(false);
});
});

describe(`${FilterCollectionActionTypes.ADD_FILTER} action`, () => {
it('should set saving to true', () => {
const result = reducer(snapshot, new AddFilterRequest(new Filter()));
expect(result.saving).toBe(true);
});
});
describe(`${FilterCollectionActionTypes.UPDATE_FILTER_REQUEST} action`, () => {
it('should set saving to true', () => {
const result = reducer(snapshot, new UpdateFilterRequest(new Filter()));
expect(result.saving).toBe(true);
});
});

describe(`${FilterCollectionActionTypes.ADD_FILTER_SUCCESS} action`, () => {
it('should set saving to true', () => {
const result = reducer(snapshot, new AddFilterSuccess(new Filter()));
expect(result).toEqual(fromFilter.initialState);
});
});
describe(`${FilterCollectionActionTypes.UPDATE_FILTER_SUCCESS} action`, () => {
it('should set saving to true', () => {
const update = {id: 'foo', changes: new Filter({id: 'foo'})};
const result = reducer(snapshot, new UpdateFilterSuccess(update));
expect(result).toEqual(fromFilter.initialState);
});
});
describe(`${searchActions.CLEAR_SEARCH} action`, () => {
it('should set saving to true', () => {
const result = reducer(snapshot, new ClearSearch());
expect(result).toEqual(fromFilter.initialState);
});
});
describe(`${actions.CANCEL_CREATE_FILTER} action`, () => {
it('should set saving to true', () => {
const result = reducer(snapshot, new CancelCreateFilter());
expect(result).toEqual(fromFilter.initialState);
});
});
});
44 changes: 44 additions & 0 deletions ui/src/app/metadata-provider/action/copy.action.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import { Action } from '@ngrx/store';
import { MetadataProvider } from '../../domain/model/metadata-provider';

export enum CopySourceActionTypes {
CREATE_PROVIDER_COPY_REQUEST = '[Copy Provider] Create Provider Copy Request',
CREATE_PROVIDER_COPY_SUCCESS = '[Copy Provider] Create Provider Copy Success',
CREATE_PROVIDER_COPY_ERROR = '[Copy Provider] Create Provider Copy Error',

UPDATE_PROVIDER_COPY = '[Copy Provider] Update Provider Copy Request',

SAVE_PROVIDER_COPY_REQUEST = '[Copy Provider] Save Provider Copy Request',
SAVE_PROVIDER_COPY_SUCCESS = '[Copy Provider] Save Provider Copy Request',
SAVE_PROVIDER_COPY_ERROR = '[Copy Provider] Save Provider Copy Request',
}

export class CreateProviderCopyRequest implements Action {
readonly type = CopySourceActionTypes.CREATE_PROVIDER_COPY_REQUEST;

constructor(public payload: { entityId: string, serviceProviderName: string, target: string }) { }
}

export class CreateProviderCopySuccess implements Action {
readonly type = CopySourceActionTypes.CREATE_PROVIDER_COPY_SUCCESS;

constructor(public payload: MetadataProvider) { }
}

export class CreateProviderCopyError implements Action {
readonly type = CopySourceActionTypes.CREATE_PROVIDER_COPY_ERROR;

constructor(public payload: Error) { }
}

export class UpdateProviderCopy implements Action {
readonly type = CopySourceActionTypes.UPDATE_PROVIDER_COPY;

constructor(public payload: Partial<MetadataProvider>) { }
}

export type CopySourceActionUnion =
| CreateProviderCopyRequest
| CreateProviderCopySuccess
| CreateProviderCopyError
| UpdateProviderCopy;
29 changes: 29 additions & 0 deletions ui/src/app/metadata-provider/action/search.action.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { Action } from '@ngrx/store';
import { MetadataProvider } from '../../domain/model/metadata-provider';

export enum SearchActionTypes {
SEARCH_IDS = '[Search Provider Ids] Request',
SEARCH_IDS_SUCCESS = '[Search Provider Ids] Success',
SEARCH_IDS_ERROR = '[Search Provider Ids] Error'
}

export class SearchIds implements Action {
readonly type = SearchActionTypes.SEARCH_IDS;

constructor(public payload: string) { }
}
export class SearchIdsSuccess implements Action {
readonly type = SearchActionTypes.SEARCH_IDS_SUCCESS;

constructor(public payload: string[]) { }
}
export class SearchIdsError implements Action {
readonly type = SearchActionTypes.SEARCH_IDS_ERROR;

constructor(public payload: any) { }
}

export type SearchActionUnion =
| SearchIds
| SearchIdsSuccess
| SearchIdsError;
Loading

0 comments on commit f550f0a

Please sign in to comment.