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', age: 43, created: '08/16/2020', balance: '12987', failedPinAttempts: 1, status: 'active', bio: 'Bodaboda', category: 'transport', gender: 'male', location: 'Bofu', locationType: 'Rural', token: 'RSV', referrer: '+25412341234'}, {id: 2, name: 'Jane Buck', phone: '+25412341234', address: '0xc86ff893ac40d3950b4d5f94a9b837258b0a9866', type: 'vendor', age: 25, created: '04/02/2020', balance: '56281', failedPinAttempts: 0, status: 'active', bio: 'Groceries', category: 'food/water', gender: 'female', location: 'Lindi', locationType: 'Urban', token: 'ERN', referrer: ''}, {id: 3, name: 'Mc Donald', phone: '+25498765432', address: '0xc86ff893ac40d3950b4d5f94a9b837258b0a9867', type: 'group', age: 31, created: '11/16/2020', balance: '450', failedPinAttempts: 2, status: 'blocked', bio: 'Food', category: 'food/water', gender: 'male', location: 'Miyani', locationType: 'Rural', token: 'RSV', referrer: '+25498769876'}, {id: 4, name: 'Hera Cles', phone: '+25498769876', address: '0xc86ff893ac40d3950b4d5f94a9b837258b0a9868', type: 'user', age: 38, created: '05/28/2020', balance: '5621', failedPinAttempts: 3, status: 'active', bio: 'Shop', category: 'shop', gender: 'female', location: 'Kayaba', locationType: 'Urban', token: 'BRT', referrer: '+25412341234'}, {id: 5, name: 'Silver Fia', phone: '+25462518374', address: '0xc86ff893ac40d3950b4d5f94a9b837258b0a9869', type: 'tokenAgent', age: 19, created: '10/10/2020', balance: '817', failedPinAttempts: 0, status: 'blocked', bio: 'Electronics', category: 'shop', gender: 'male', location: 'Mkanyeni', locationType: 'Rural', token: 'RSV', referrer: '+25412345678'}, ]; 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, next: HttpHandler): Observable> { 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 { 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 { return ok(accounts); } function getAccountById(): Observable { const queriedAccount = accounts.find(account => account.id === idFromUrl()); return ok(queriedAccount); } function getActions(): Observable { return ok(actions); } function getActionById(): Observable { const queriedAction = actions.find(action => action.id === idFromUrl()); return ok(queriedAction); } function approveAction(): Observable { 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 { const queriedUserHistory = histories.filter(history => history.userId === idFromUrl()); return ok(queriedUserHistory); } function getLocations(): Observable { return ok(locations); } function getStaff(): Observable { return ok(staffMembers); } function getStaffById(): Observable { const queriedStaff = staffMembers.find(staff => staff.id === idFromUrl()); return ok(queriedStaff); } function changeStaffStatus(): Observable { 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 { 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 { return ok(tokens); } function getTokenBySymbol(): Observable { const queriedToken = tokens.find(token => token.symbol === stringFromUrl()); return ok(queriedToken); } // helper functions function ok(body): Observable { return of(new HttpResponse({ status: 200, body })); } function error(message): Observable { 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 };