220 lines
10 KiB
TypeScript
220 lines
10 KiB
TypeScript
|
import {HTTP_INTERCEPTORS, HttpEvent, HttpHandler, HttpInterceptor, HttpRequest, HttpResponse} from '@angular/common/http';
|
||
|
import {Injectable} from '@angular/core';
|
||
|
import {Observable, of, throwError} from 'rxjs';
|
||
|
import {delay, dematerialize, materialize, mergeMap} from 'rxjs/operators';
|
||
|
|
||
|
const accounts = [
|
||
|
{id: 1, name: 'John Doe', phone: '+25412345678', address: '0xc86ff893ac40d3950b4d5f94a9b837258b0a9865', type: 'user', created: '08/16/2020', balance: '12987', failedPinAttempts: 1, status: 'approved', bio: 'Bodaboda', category: 'transport', gender: 'male', location: 'Bofu', token: 'RSV', referrer: 'Jane Buck'},
|
||
|
{id: 2, name: 'Jane Buck', phone: '+25412341234', address: '0xc86ff893ac40d3950b4d5f94a9b837258b0a9865', type: 'vendor', created: '04/02/2020', balance: '56281', failedPinAttempts: 0, status: 'approved', bio: 'Groceries', category: 'food/water', gender: 'female', location: 'Lindi', token: 'ERN', referrer: ''},
|
||
|
{id: 3, name: 'Mc Donald', phone: '+25498765432', address: '0xc86ff893ac40d3950b4d5f94a9b837258b0a9865', type: 'group', created: '11/16/2020', balance: '450', failedPinAttempts: 2, status: 'unapproved', bio: 'Food', category: 'food/water', gender: 'male', location: 'Miyani', token: 'RSV', referrer: 'Hera Cles'},
|
||
|
{id: 4, name: 'Hera Cles', phone: '+25498769876', address: '0xc86ff893ac40d3950b4d5f94a9b837258b0a9865', type: 'user', created: '05/28/2020', balance: '5621', failedPinAttempts: 3, status: 'approved', bio: 'Shop', category: 'shop', gender: 'female', location: 'Kayaba', token: 'BRT', referrer: 'Jane Buck'},
|
||
|
{id: 5, name: 'Silver Fia', phone: '+25462518374', address: '0xc86ff893ac40d3950b4d5f94a9b837258b0a9865', type: 'tokenAgent', created: '10/10/2020', balance: '817', failedPinAttempts: 0, status: 'unapproved', bio: 'Electronics', category: 'shop', gender: 'male', location: 'Mkanyeni', token: 'RSV', referrer: 'John Doe'},
|
||
|
];
|
||
|
|
||
|
const actions = [
|
||
|
{ id: 1, user: 'Tom', role: 'enroller', action: 'Disburse RSV 100', approval: false },
|
||
|
{ id: 2, user: 'Christine', role: 'admin', action: 'Change user phone number', approval: true },
|
||
|
{ id: 3, user: 'Will', role: 'superadmin', action: 'Reclaim RSV 1000', approval: true },
|
||
|
{ id: 4, user: 'Vivian', role: 'enroller', action: 'Complete user profile', approval: true },
|
||
|
{ id: 5, user: 'Jack', role: 'enroller', action: 'Reclaim RSV 200', approval: false },
|
||
|
{ id: 6, user: 'Patience', role: 'enroller', action: 'Change user information', approval: false }
|
||
|
];
|
||
|
|
||
|
const histories = [
|
||
|
{ id: 1, userId: 3, userName: 'Mc Donald', action: 'Receive RSV 100', staff: 'Tom', timestamp: Date.now() },
|
||
|
{ id: 2, userId: 5, userName: 'Silver Fia', action: 'Change phone number from +25412345678 to +25498765432', staff: 'Christine', timestamp: Date.now()},
|
||
|
{ id: 3, userId: 4, userName: 'Hera Cles', action: 'Completed user profile', staff: 'Vivian', timestamp: Date.now() },
|
||
|
];
|
||
|
|
||
|
const locations: any = [
|
||
|
{ name: 'Kwale',
|
||
|
districts: [
|
||
|
{ name: 'Kinango',
|
||
|
locations: [
|
||
|
{ name: 'Bofu', villages: ['Bofu', 'Chidzuvini', 'Mkanyeni']},
|
||
|
{ name: 'Mnyenzeni', villages: ['Miloeni', 'Miyani', 'Mnyenzeni', 'Vikolani', 'Vitangani']}
|
||
|
]
|
||
|
}
|
||
|
]
|
||
|
},
|
||
|
{ name: 'Nairobi',
|
||
|
districts: [
|
||
|
{ name: 'Dagorreti',
|
||
|
locations: [
|
||
|
{ name: 'Kawangware', villages: ['Congo']},
|
||
|
]
|
||
|
},
|
||
|
{ name: 'Ngong',
|
||
|
locations: [
|
||
|
{ name: 'Kibera', villages: ['Kibera', 'Lindi']},
|
||
|
]
|
||
|
},
|
||
|
{ name: 'South B',
|
||
|
locations: [
|
||
|
{ name: 'Mukuru', villages: ['Kayaba']},
|
||
|
{ name: 'South B', villages: ['South B']},
|
||
|
]
|
||
|
},
|
||
|
]
|
||
|
}
|
||
|
];
|
||
|
|
||
|
const staffMembers = [
|
||
|
{ id: 1, name: 'admin@acme.org', accountType: 'Admin', created: '17/11/2020', status: 'activated'},
|
||
|
{ id: 2, name: 'will@grassecon.org', accountType: 'SuperAdmin', created: '17/11/2020', status: 'activated'},
|
||
|
{ id: 3, name: 'spence@grassecon.org', accountType: 'Enroller', created: '17/11/2020', status: 'activated'},
|
||
|
{ id: 4, name: 'admin@redcross.org', accountType: 'View', created: '17/11/2020', status: 'activated'}
|
||
|
];
|
||
|
|
||
|
const tokens = [
|
||
|
{name: 'Giftable Reserve', symbol: 'GRZ', address: '0xa686005CE37Dce7738436256982C3903f2E4ea8E', supply: '1000000001000000000000000000', decimals: '18', reserves: {}},
|
||
|
{name: 'Demo Token', symbol: 'DEMO', address: '0xc80D6aFF8194114c52AEcD84c9f15fd5c8abb187', supply: '99999999999999998976', decimals: '18', reserves: {'0xa686005CE37Dce7738436256982C3903f2E4ea8E': {weight: '1000000', balance: '99999999999999998976'}}, reserveRatio: '1000000', owner: '0x3Da99AAD2D9CA01D131eFc3B17444b832B31Ff4a'},
|
||
|
{name: 'Foo Token', symbol: 'FOO', address: '0x9ceD86089f7aBB5A97B40eb0E7521e7aa308d354', supply: '1000000000000000001014', decimals: '18', reserves: {'0xa686005CE37Dce7738436256982C3903f2E4ea8E': {weight: '1000000', balance: '1000000000000000001014'}}, reserveRatio: '1000000', owner: '0x3Da99AAD2D9CA01D131eFc3B17444b832B31Ff4a'},
|
||
|
{name: 'testb', symbol: 'tstb', address: '0xC63cFA91A3BFf41cE31Ff436f67D3ACBC977DB95', supply: '99000', decimals: '18', reserves: {'0xa686005CE37Dce7738436256982C3903f2E4ea8E': {weight: '1000000', balance: '99000'}}, reserveRatio: '1000000', owner: '0x3Da99AAD2D9CA01D131eFc3B17444b832B31Ff4a'},
|
||
|
{name: 'testa', symbol: 'tsta', address: '0x8fA4101ef19D0a078239d035659e92b278bD083C', supply: '9981', decimals: '18', reserves: {'0xa686005CE37Dce7738436256982C3903f2E4ea8E': {weight: '1000000', balance: '9981'}}, reserveRatio: '1000000', owner: '0x3Da99AAD2D9CA01D131eFc3B17444b832B31Ff4a'},
|
||
|
{name: 'testc', symbol: 'tstc', address: '0x4A6fA6bc3BfE4C9661bC692D9798425350C9e3D4', supply: '100990', decimals: '18', reserves: {'0xa686005CE37Dce7738436256982C3903f2E4ea8E': {weight: '1000000', balance: '100990'}}, reserveRatio: '1000000', owner: '0x3Da99AAD2D9CA01D131eFc3B17444b832B31Ff4a'}
|
||
|
];
|
||
|
|
||
|
@Injectable()
|
||
|
export class MockBackendInterceptor implements HttpInterceptor {
|
||
|
intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
|
||
|
const { url, method, headers, body } = request;
|
||
|
|
||
|
// wrap in delayed observable to simulate server api call\
|
||
|
// call materialize and dematerialize to ensure delay even is thrown
|
||
|
return of(null)
|
||
|
.pipe(mergeMap(handleRoute))
|
||
|
.pipe(materialize())
|
||
|
.pipe(delay(500))
|
||
|
.pipe(dematerialize());
|
||
|
|
||
|
function handleRoute(): Observable<any> {
|
||
|
switch (true) {
|
||
|
case url.endsWith('/accounts') && method === 'GET':
|
||
|
return getAccounts();
|
||
|
case url.match(/\/accounts\/\d+$/) && method === 'GET':
|
||
|
return getAccountById();
|
||
|
case url.endsWith('/actions') && method === 'GET':
|
||
|
return getActions();
|
||
|
case url.match(/\/actions\/\d+$/) && method === 'GET':
|
||
|
return getActionById();
|
||
|
case url.match(/\/actions\/\d+$/) && method === 'POST':
|
||
|
return approveAction();
|
||
|
case url.match(/\/history\/\d+$/) && method === 'GET':
|
||
|
return getHistoryByUser();
|
||
|
case url.endsWith('/locations') && method === 'GET':
|
||
|
return getLocations();
|
||
|
case url.endsWith('/staff') && method === 'GET':
|
||
|
return getStaff();
|
||
|
case url.match(/\/staff\/\d+$/) && method === 'GET':
|
||
|
return getStaffById();
|
||
|
case url.match(/\/staff\/\d+$/) && method === 'POST' && body.status !== undefined:
|
||
|
return changeStaffStatus();
|
||
|
case url.match(/\/staff\/\d+$/) && method === 'POST' && body.accountType !== undefined:
|
||
|
return changeStaffType();
|
||
|
case url.endsWith('/tokens') && method === 'GET':
|
||
|
return getTokens();
|
||
|
case url.match(/\/tokens\/\w+$/) && method === 'GET':
|
||
|
return getTokenBySymbol();
|
||
|
default:
|
||
|
// pass through any requests not handled above
|
||
|
return next.handle(request);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// route functions
|
||
|
|
||
|
function getAccounts(): Observable<any> {
|
||
|
return ok(accounts);
|
||
|
}
|
||
|
|
||
|
function getAccountById(): Observable<any> {
|
||
|
const queriedAccount = accounts.find(account => account.id === idFromUrl());
|
||
|
return ok(queriedAccount);
|
||
|
}
|
||
|
|
||
|
function getActions(): Observable<any> {
|
||
|
return ok(actions);
|
||
|
}
|
||
|
|
||
|
function getActionById(): Observable<any> {
|
||
|
const queriedAction = actions.find(action => action.id === idFromUrl());
|
||
|
return ok(queriedAction);
|
||
|
}
|
||
|
|
||
|
function approveAction(): Observable<any> {
|
||
|
const queriedAction = actions.find(action => action.id === idFromUrl());
|
||
|
queriedAction.approval = body.approval;
|
||
|
const message = `Action approval status set to ${body.approval} successfully!`;
|
||
|
return ok(message);
|
||
|
}
|
||
|
|
||
|
function getHistoryByUser(): Observable<any> {
|
||
|
const queriedUserHistory = histories.filter(history => history.userId === idFromUrl());
|
||
|
return ok(queriedUserHistory);
|
||
|
}
|
||
|
|
||
|
function getLocations(): Observable<any> {
|
||
|
return ok(locations);
|
||
|
}
|
||
|
|
||
|
function getStaff(): Observable<any> {
|
||
|
return ok(staffMembers);
|
||
|
}
|
||
|
|
||
|
function getStaffById(): Observable<any> {
|
||
|
const queriedStaff = staffMembers.find(staff => staff.id === idFromUrl());
|
||
|
return ok(queriedStaff);
|
||
|
}
|
||
|
|
||
|
function changeStaffStatus(): Observable<any> {
|
||
|
const queriedStaff = staffMembers.find(staff => staff.id === idFromUrl());
|
||
|
queriedStaff.status = body.status;
|
||
|
const message = `Staff account status changed to ${body.status} successfully!`;
|
||
|
return ok(message);
|
||
|
}
|
||
|
|
||
|
function changeStaffType(): Observable<any> {
|
||
|
const queriedStaff = staffMembers.find(staff => staff.id === idFromUrl());
|
||
|
queriedStaff.accountType = body.accountType;
|
||
|
const message = `Staff account type changed to ${body.accountType} successfully!`;
|
||
|
return ok(message);
|
||
|
}
|
||
|
|
||
|
function getTokens(): Observable<any> {
|
||
|
return ok(tokens);
|
||
|
}
|
||
|
|
||
|
function getTokenBySymbol(): Observable<any> {
|
||
|
const queriedToken = tokens.find(token => token.symbol === stringFromUrl());
|
||
|
return ok(queriedToken);
|
||
|
}
|
||
|
|
||
|
// helper functions
|
||
|
|
||
|
function ok(body): Observable<any> {
|
||
|
return of(new HttpResponse({ status: 200, body }));
|
||
|
}
|
||
|
|
||
|
function error(message): Observable<any> {
|
||
|
return throwError({ status: 400, error: { message } });
|
||
|
}
|
||
|
|
||
|
function idFromUrl(): number {
|
||
|
const urlParts = url.split('/');
|
||
|
return parseInt(urlParts[urlParts.length - 1], 10);
|
||
|
}
|
||
|
|
||
|
function stringFromUrl(): string {
|
||
|
const urlParts = url.split('/');
|
||
|
return urlParts[urlParts.length - 1];
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
export const MockBackendProvider = {
|
||
|
provide: HTTP_INTERCEPTORS,
|
||
|
useClass: MockBackendInterceptor,
|
||
|
multi: true
|
||
|
};
|