cic-staff-client/src/app/_helpers/mock-backend.ts

1248 lines
25 KiB
TypeScript

// Core imports
import {
HTTP_INTERCEPTORS,
HttpEvent,
HttpHandler,
HttpInterceptor,
HttpRequest,
HttpResponse,
} from '@angular/common/http';
import { Injectable } from '@angular/core';
// Third party imports
import { Observable, of, throwError } from 'rxjs';
import { delay, dematerialize, materialize, mergeMap } from 'rxjs/operators';
// Application imports
import { Action, AreaName, AreaType, Category, Token } from '@app/_models';
/** A mock of the curated account types. */
const accountTypes: Array<string> = ['user', 'cashier', 'vendor', 'tokenagent', 'group'];
/** A mock of actions made by the admin staff. */
const actions: Array<Action> = [
{ 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 },
];
/** A mock of curated area names. */
const areaNames: Array<AreaName> = [
{
name: 'Mukuru Nairobi',
locations: [
'kayaba',
'kayba',
'kambi',
'mukuru',
'masai',
'hazina',
'south',
'tetra',
'tetrapak',
'ruben',
'rueben',
'kingston',
'korokocho',
'kingstone',
'kamongo',
'lungalunga',
'sinai',
'sigei',
'lungu',
'lunga lunga',
'owino road',
'seigei',
],
},
{
name: 'Kinango Kwale',
locations: [
'amani',
'bofu',
'chibuga',
'chikomani',
'chilongoni',
'chigojoni',
'chinguluni',
'chigato',
'chigale',
'chikole',
'chilongoni',
'chilumani',
'chigojoni',
'chikomani',
'chizini',
'chikomeni',
'chidzuvini',
'chidzivuni',
'chikuyu',
'chizingo',
'doti',
'dzugwe',
'dzivani',
'dzovuni',
'hanje',
'kasemeni',
'katundani',
'kibandaogo',
'kibandaongo',
'kwale',
'kinango',
'kidzuvini',
'kalalani',
'kafuduni',
'kaloleni',
'kilibole',
'lutsangani',
'peku',
'gona',
'guro',
'gandini',
'mkanyeni',
'myenzeni',
'miyenzeni',
'miatsiani',
'mienzeni',
'mnyenzeni',
'minyenzeni',
'miyani',
'mioleni',
'makuluni',
'mariakani',
'makobeni',
'madewani',
'mwangaraba',
'mwashanga',
'miloeni',
'mabesheni',
'mazeras',
'mazera',
'mlola',
'muugano',
'mulunguni',
'mabesheni',
'miatsani',
'miatsiani',
'mwache',
'mwangani',
'mwehavikonje',
'miguneni',
'nzora',
'nzovuni',
'vikinduni',
'vikolani',
'vitangani',
'viogato',
'vyogato',
'vistangani',
'yapha',
'yava',
'yowani',
'ziwani',
'majengo',
'matuga',
'vigungani',
'vidziweni',
'vinyunduni',
'ukunda',
'kokotoni',
'mikindani',
],
},
{
name: 'Misc Nairobi',
locations: [
'nairobi',
'west',
'lindi',
'kibera',
'kibira',
'kibra',
'makina',
'soweto',
'olympic',
'kangemi',
'ruiru',
'congo',
'kawangware',
'kwangware',
'donholm',
'dagoreti',
'dandora',
'kabete',
'sinai',
'donhom',
'donholm',
'huruma',
'kitengela',
'makadara',
',mlolongo',
'kenyatta',
'mlolongo',
'tassia',
'tasia',
'gatina',
'56',
'industrial',
'kariobangi',
'kasarani',
'kayole',
'mathare',
'pipe',
'juja',
'uchumi',
'jogoo',
'umoja',
'thika',
'kikuyu',
'stadium',
'buru buru',
'ngong',
'starehe',
'mwiki',
'fuata',
'kware',
'kabiro',
'embakassi',
'embakasi',
'kmoja',
'east',
'githurai',
'landi',
'langata',
'limuru',
'mathere',
'dagoretti',
'kirembe',
'muugano',
'mwiki',
'toi market',
],
},
{
name: 'Misc Mombasa',
locations: [
'mombasa',
'likoni',
'bangla',
'bangladesh',
'kizingo',
'old town',
'makupa',
'mvita',
'ngombeni',
'ngómbeni',
'ombeni',
'magongo',
'miritini',
'changamwe',
'jomvu',
'ohuru',
'tudor',
'diani',
],
},
{
name: 'Kisauni',
locations: [
'bamburi',
'kisauni',
'mworoni',
'nyali',
'shanzu',
'bombolulu',
'mtopanga',
'mjambere',
'majaoni',
'manyani',
'magogoni',
'junda',
'mwakirunge',
'mshomoroni',
],
},
{
name: 'Kilifi',
locations: [
'kilfi',
'kilifi',
'mtwapa',
'takaungu',
'makongeni',
'mnarani',
'mnarani',
'office',
'g.e',
'ge',
'raibai',
'ribe',
],
},
{
name: 'Kakuma',
locations: ['kakuma'],
},
{
name: 'Kitui',
locations: ['kitui', 'mwingi'],
},
{
name: 'Nyanza',
locations: [
'busia',
'nyalgunga',
'mbita',
'siaya',
'kisumu',
'nyalenda',
'hawinga',
'rangala',
'uyoma',
'mumias',
'homabay',
'homaboy',
'migori',
'kusumu',
],
},
{
name: 'Misc Rural Counties',
locations: [
'makueni',
'meru',
'kisii',
'bomet',
'machakos',
'bungoma',
'eldoret',
'kakamega',
'kericho',
'kajiado',
'nandi',
'nyeri',
'wote',
'kiambu',
'mwea',
'nakuru',
'narok',
],
},
{
name: 'other',
locations: ['other', 'none', 'unknown'],
},
];
/** A mock of curated area types. */
const areaTypes: Array<AreaType> = [
{
name: 'urban',
area: ['urban', 'nairobi', 'mombasa'],
},
{
name: 'rural',
area: ['rural', 'kakuma', 'kwale', 'kinango', 'kitui', 'nyanza'],
},
{
name: 'periurban',
area: ['kilifi', 'periurban'],
},
{
name: 'other',
area: ['other'],
},
];
/** A mock of the user's business categories */
const categories: Array<Category> = [
{
name: 'system',
products: ['system', 'office main', 'office main phone'],
},
{
name: 'education',
products: [
'book',
'coach',
'teacher',
'sch',
'school',
'pry',
'education',
'student',
'mwalimu',
'maalim',
'consultant',
'consult',
'college',
'university',
'lecturer',
'primary',
'secondary',
'daycare',
'babycare',
'baby care',
'elim',
'eimu',
'nursery',
'red cross',
'volunteer',
'instructor',
'journalist',
'lesson',
'academy',
'headmistress',
'headteacher',
'cyber',
'researcher',
'professor',
'demo',
'expert',
'tution',
'tuition',
'children',
'headmaster',
'educator',
'Marital counsellor',
'counsellor',
'trainer',
'vijana',
'youth',
'intern',
'redcross',
'KRCS',
'danish',
'science',
'data',
'facilitator',
'vitabu',
'kitabu',
],
},
{
name: 'faith',
products: [
'pastor',
'imam',
'madrasa',
'religous',
'religious',
'ustadh',
'ustadhi',
'Marital counsellor',
'counsellor',
'church',
'kanisa',
'mksiti',
'donor',
],
},
{
name: 'government',
products: [
'elder',
'chief',
'police',
'government',
'country',
'county',
'soldier',
'village admin',
'ward',
'leader',
'kra',
'mailman',
'immagration',
'immigration',
],
},
{
name: 'environment',
products: [
'conservation',
'toilet',
'choo',
'garbage',
'fagio',
'waste',
'tree',
'taka',
'scrap',
'cleaning',
'gardener',
'rubbish',
'usafi',
'mazingira',
'miti',
'trash',
'cleaner',
'plastic',
'collection',
'seedling',
'seedlings',
'recycling',
],
},
{
name: 'farming',
products: [
'farm',
'farmer',
'farming',
'mkulima',
'kulima',
'ukulima',
'wakulima',
'jembe',
'shamba',
],
},
{
name: 'labour',
products: [
'artist',
'agent',
'guard',
'askari',
'accountant',
'baker',
'beadwork',
'beauty',
'business',
'barber',
'casual',
'electrian',
'caretaker',
'car wash',
'capenter',
'construction',
'chef',
'catering',
'cobler',
'cobbler',
'carwash',
'dhobi',
'landlord',
'design',
'carpenter',
'fundi',
'hawking',
'hawker',
'househelp',
'hsehelp',
'house help',
'help',
'housegirl',
'kushona',
'juakali',
'jualikali',
'juacali',
'jua kali',
'shepherd',
'makuti',
'kujenga',
'kinyozi',
'kazi',
'knitting',
'kufua',
'fua',
'hustler',
'biashara',
'labour',
'labor',
'laundry',
'repair',
'hair',
'posho',
'mill',
'mtambo',
'uvuvi',
'engineer',
'manager',
'tailor',
'nguo',
'mason',
'mtumba',
'garage',
'mechanic',
'mjenzi',
'mfugaji',
'painter',
'receptionist',
'printing',
'programming',
'plumb',
'charging',
'salon',
'mpishi',
'msusi',
'mgema',
'footballer',
'photocopy',
'peddler',
'staff',
'sales',
'service',
'saloon',
'seremala',
'security',
'insurance',
'secretary',
'shoe',
'shepard',
'shephard',
'tout',
'tv',
'mvuvi',
'mawe',
'majani',
'maembe',
'freelance',
'mjengo',
'electronics',
'photographer',
'programmer',
'electrician',
'washing',
'bricks',
'welder',
'welding',
'working',
'worker',
'watchman',
'waiter',
'waitress',
'viatu',
'yoga',
'guitarist',
'house',
'artisan',
'musician',
'trade',
'makonge',
'ujenzi',
'vendor',
'watchlady',
'marketing',
'beautician',
'photo',
'metal work',
'supplier',
'law firm',
'brewer',
],
},
{
name: 'food',
products: [
'avocado',
'bhajia',
'bajia',
'mbonga',
'bofu',
'beans',
'biscuits',
'biringanya',
'banana',
'bananas',
'crisps',
'chakula',
'coconut',
'chapati',
'cereal',
'chipo',
'chapo',
'chai',
'chips',
'cassava',
'cake',
'cereals',
'cook',
'corn',
'coffee',
'chicken',
'dagaa',
'donut',
'dough',
'groundnuts',
'hotel',
'holel',
'hoteli',
'butcher',
'butchery',
'fruit',
'food',
'fruits',
'fish',
'githeri',
'grocery',
'grocer',
'pojo',
'papa',
'goats',
'mabenda',
'mbenda',
'poultry',
'soda',
'peanuts',
'potatoes',
'samosa',
'soko',
'samaki',
'tomato',
'tomatoes',
'mchele',
'matunda',
'mango',
'melon',
'mellon',
'nyanya',
'nyama',
'omena',
'umena',
'ndizi',
'njugu',
'kamba kamba',
'khaimati',
'kaimati',
'kunde',
'kuku',
'kahawa',
'keki',
'muguka',
'miraa',
'milk',
'choma',
'maziwa',
'mboga',
'mbog',
'busaa',
'chumvi',
'cabbages',
'mabuyu',
'machungwa',
'mbuzi',
'mnazi',
'mchicha',
'ngombe',
'ngano',
'nazi',
'oranges',
'peanuts',
'mkate',
'bread',
'mikate',
'vitungu',
'sausages',
'maize',
'mbata',
'mchuzi',
'mchuuzi',
'mandazi',
'mbaazi',
'mahindi',
'maandazi',
'mogoka',
'meat',
'mhogo',
'mihogo',
'muhogo',
'maharagwe',
'miwa',
'mahamri',
'mitumba',
'simsim',
'porridge',
'pilau',
'vegetable',
'egg',
'mayai',
'mifugo',
'unga',
'good',
'sima',
'sweet',
'sweats',
'sambusa',
'snacks',
'sugar',
'suger',
'ugoro',
'sukari',
'soup',
'spinach',
'smokie',
'smokies',
'sukuma',
'tea',
'uji',
'ugali',
'uchuzi',
'uchuuzi',
'viazi',
'yoghurt',
'yogurt',
'wine',
'marondo',
'maandzi',
'matoke',
'omeno',
'onions',
'nzugu',
'korosho',
'barafu',
'juice',
],
},
{
name: 'water',
products: ['maji', 'water'],
},
{
name: 'health',
products: [
'agrovet',
'dispensary',
'barakoa',
'chemist',
'Chemicals',
'chv',
'doctor',
'daktari',
'dawa',
'hospital',
'herbalist',
'mganga',
'sabuni',
'soap',
'nurse',
'heath',
'community health worker',
'clinic',
'clinical',
'mask',
'medicine',
'lab technician',
'pharmacy',
'cosmetics',
'veterinary',
'vet',
'sickly',
'emergency response',
'emergency',
],
},
{
name: 'savings',
products: ['chama', 'group', 'savings', 'loan', 'silc', 'vsla', 'credit', 'finance'],
},
{
name: 'shop',
products: [
'bag',
'bead',
'belt',
'bedding',
'jik',
'bed',
'cement',
'botique',
'boutique',
'lines',
'kibanda',
'kiosk',
'spareparts',
'candy',
'cloth',
'electricals',
'mutumba',
'cafe',
'leso',
'lesso',
'duka',
'spare parts',
'socks',
'malimali',
'mitungi',
'mali mali',
'hardware',
'detergent',
'detergents',
'dera',
'retail',
'kamba',
'pombe',
'pampers',
'pool',
'phone',
'simu',
'mangwe',
'mikeka',
'movie',
'shop',
'acces',
'mchanga',
'uto',
'airtime',
'matress',
'mattress',
'mattresses',
'mpsea',
'mpesa',
'shirt',
'wholesaler',
'perfume',
'playstation',
'tissue',
'vikapu',
'uniform',
'flowers',
'vitenge',
'utencils',
'utensils',
'station',
'jewel',
'pool table',
'club',
'pub',
'bar',
'furniture',
'm-pesa',
'vyombo',
],
},
{
name: 'transport',
products: [
'kebeba',
'beba',
'bebabeba',
'bike',
'bicycle',
'matatu',
'boda',
'bodaboda',
'cart',
'carrier',
'tour',
'travel',
'driver',
'dereva',
'tout',
'conductor',
'kubeba',
'tuktuk',
'taxi',
'piki',
'pikipiki',
'manamba',
'trasportion',
'mkokoteni',
'mover',
'motorist',
'motorbike',
'transport',
'transpoter',
'gari',
'magari',
'makanga',
'car',
],
},
{
name: 'fuel/energy',
products: [
'timber',
'timberyard',
'biogas',
'charcol',
'charcoal',
'kuni',
'mbao',
'fuel',
'makaa',
'mafuta',
'moto',
'solar',
'stima',
'fire',
'firewood',
'wood',
'oil',
'taa',
'gas',
'paraffin',
'parrafin',
'parafin',
'petrol',
'petro',
'kerosine',
'kerosene',
'diesel',
],
},
{
name: 'other',
products: ['other', 'none', 'unknown', 'none'],
},
];
/** A mock of curated genders */
const genders: Array<string> = ['male', 'female', 'other'];
/** A mock of the tokens in the system. */
const tokens: Array<Token> = [
{
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',
},
];
/** A mock of curated transaction types. */
const transactionTypes: Array<string> = [
'transactions',
'conversions',
'disbursements',
'rewards',
'reclamation',
];
/**
* Intercepts HTTP requests and handles some specified requests internally.
* Provides a backend that can handle requests for certain data items.
*/
@Injectable()
export class MockBackendInterceptor implements HttpInterceptor {
/**
* Intercepts HTTP requests.
*
* @param request - An outgoing HTTP request with an optional typed body.
* @param next - The next HTTP handler or the outgoing request dispatcher.
* @returns The response from the resolved request.
*/
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());
/** Forward requests from select routes to their internal handlers. */
function handleRoute(): Observable<any> {
switch (true) {
case url.endsWith('/accounttypes') && method === 'GET':
return getAccountTypes();
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.endsWith('/areanames') && method === 'GET':
return getAreaNames();
case url.match(/\/areanames\/\w+$/) && method === 'GET':
return getAreaNameByLocation();
case url.endsWith('/areatypes') && method === 'GET':
return getAreaTypes();
case url.match(/\/areatypes\/\w+$/) && method === 'GET':
return getAreaTypeByArea();
case url.endsWith('/categories') && method === 'GET':
return getCategories();
case url.match(/\/categories\/\w+$/) && method === 'GET':
return getCategoryByProduct();
case url.endsWith('/genders') && method === 'GET':
return getGenders();
case url.endsWith('/tokens') && method === 'GET':
return getTokens();
case url.match(/\/tokens\/\w+$/) && method === 'GET':
return getTokenBySymbol();
case url.endsWith('/transactiontypes') && method === 'GET':
return getTransactionTypes();
default:
// pass through any requests not handled above
return next.handle(request);
}
}
// route functions
function approveAction(): Observable<HttpResponse<any>> {
const queriedAction: Action = actions.find((action) => action.id === idFromUrl());
queriedAction.approval = body.approval;
const message: string = `Action approval status set to ${body.approval} successfully!`;
return ok(message);
}
function getAccountTypes(): Observable<HttpResponse<any>> {
return ok(accountTypes);
}
function getActions(): Observable<HttpResponse<any>> {
return ok(actions);
}
function getActionById(): Observable<HttpResponse<any>> {
const queriedAction: Action = actions.find((action) => action.id === idFromUrl());
return ok(queriedAction);
}
function getAreaNames(): Observable<HttpResponse<any>> {
const areaNameList: Array<string> = areaNames.map((areaName) => areaName.name);
return ok(areaNameList);
}
function getAreaNameByLocation(): Observable<HttpResponse<any>> {
const queriedAreaName: AreaName = areaNames.find((areaName) =>
areaName.locations.includes(stringFromUrl())
);
return ok(queriedAreaName.name || 'other');
}
function getAreaTypes(): Observable<HttpResponse<any>> {
const areaTypeList: Array<string> = areaTypes.map((areaType) => areaType.name);
return ok(areaTypeList);
}
function getAreaTypeByArea(): Observable<HttpResponse<any>> {
const queriedAreaType: AreaType = areaTypes.find((areaType) =>
areaType.area.includes(stringFromUrl())
);
return ok(queriedAreaType.name || 'other');
}
function getCategories(): Observable<HttpResponse<any>> {
const categoryList: Array<string> = categories.map((category) => category.name);
return ok(categoryList);
}
function getCategoryByProduct(): Observable<HttpResponse<any>> {
const queriedCategory: Category = categories.find((category) =>
category.products.includes(stringFromUrl())
);
return ok(queriedCategory.name || 'other');
}
function getGenders(): Observable<HttpResponse<any>> {
return ok(genders);
}
function getTokens(): Observable<HttpResponse<any>> {
return ok(tokens);
}
function getTokenBySymbol(): Observable<HttpResponse<any>> {
const queriedToken: Token = tokens.find((token) => token.symbol === stringFromUrl());
return ok(queriedToken);
}
function getTransactionTypes(): Observable<HttpResponse<any>> {
return ok(transactionTypes);
}
// helper functions
function error(message): Observable<any> {
return throwError({ status: 400, error: { message } });
}
function idFromUrl(): number {
const urlParts: Array<string> = url.split('/');
return parseInt(urlParts[urlParts.length - 1], 10);
}
function ok(responseBody: any): Observable<HttpResponse<any>> {
return of(new HttpResponse({ status: 200, body: responseBody }));
}
function stringFromUrl(): string {
const urlParts: Array<string> = url.split('/');
return urlParts[urlParts.length - 1];
}
}
}
/** Exports the MockBackendInterceptor as an Angular provider. */
export const MockBackendProvider = {
provide: HTTP_INTERCEPTORS,
useClass: MockBackendInterceptor,
multi: true,
};