/**
* @module method/testControl
*/
const getUserMeta = require('./get');
const updateUserMeta = require('./update');
const admin = require('firebase-admin');
const functions = require('firebase-functions');
const axios = require('axios');
const db = admin.firestore();
const FieldValue = admin.firestore.FieldValue;
const Timestamp = admin.firestore.Timestamp;
const { loandisk, simplybook } = functions.config();
// Hard-coded to make sure only dev branch will be affected
const branchId = '8895';
const config = {
headers: {
'Content-Type': 'application/json',
'Authorization': `Basic ${loandisk.authcode}`,
},
};
const simplybookApi = axios.create({
baseURL: 'https://user-api-v2.simplybook.me/', // NOTE: This uses the v2 ReST API
headers: {
'Content-Type': 'application/json',
'X-Company-Login': simplybook.company,
}
});
/**
* Run a command to control the test environment
*
* - resetData: Resets all Firestore, Loandisk and Firebase Auth records to their initial state.
* - unlockReloanAppointment - Allows the given user to make an appointment.
*
* @requires method/get
* @requires method/update
*
* @param {object} data - The data object attached to the request
* @param {string} data.command - The command to execute
* @param {object} data.params - Object with named parameters for the command
*
* @return {(string|boolean)} True if the command is executed, otherwise false.
*/
const testControl = {
run: async ({ command, params }) => {
// TODO Authorization?
switch (command) {
case 'resetData':
await testControl.resetData();
break;
case 'unlockReloanAppointment':
await updateUserMeta({
uid: params.uid,
appointmentType: params.appointmentType,
})
break;
default:
console.warn(`Unknown command: ${command}`)
return false;
}
return true;
},
resetData: () => {
return Promise.all([
// Delete everything
getUserMeta({
uid: 'hk_wx0000009',
}).then((userMeta) => {
return Promise.all([
testControl.cancelAppointmentForUserSync(userMeta),
testControl.deleteUserSync(userMeta),
])
}),
// Delete reloan data
getUserMeta({
uid: 'hk_wx1111114',
}).then((userMeta) => {
return testControl.cancelAppointmentForUserSync(userMeta);
}),
testControl.updateUserMetaForUid({
uid: 'hk_wx1111114',
hasReloanPhoneNumber: FieldValue.delete(),
reloanStartTime: FieldValue.delete(),
appointmentType: FieldValue.delete(),
}),
// Reset expired reloan application
testControl.updateUserMetaForUid({
uid: 'hk_wx222222a',
hasReloanPhoneNumber: "Yes",
reloanStartTime: Timestamp.fromMillis(0),
}),
// Reset loan release date and status
testControl.resetWX40Loan(),
// Delete simplybook appointment and reset account to initial state
getUserMeta({
uid: 'hk_wx5555556',
}).then((userMeta) => {
return testControl.cancelAppointmentForUserSync(userMeta);
}).then((response) => {
testControl.updateUserMetaForUid({
uid: 'hk_wx5555556',
borrowerID: 1305255,
branchID: 8895,
country: 'HK',
failCount: 0,
idNumber: 'WX555555(6)',
passwordHash: 'af41e68e1309fa29a5044cbdc36b90a3821d8807e68c7675a6c495112bc8a55f',
}, true)
}),
]).then(() => {
return true
});
},
cancelAppointmentForUserSync: async ({bookingID, uid}) => {
if (bookingID !== undefined) {
const authResponse = await simplybookApi.post('/admin/auth', {
"company": simplybook.company,
"login": simplybook.username,
"password": simplybook.password
});
const deleteResponse = await simplybookApi.delete(`/admin/bookings/${bookingID}`, {
headers: {
'X-Token': authResponse.data.token,
}
});
const { status } = deleteResponse.data;
if (status === 'canceled') {
console.info(`[Success] Deleted booking ${bookingID} for ${uid}`)
return deleteResponse;
} else {
console.warn(`[Warning] Unable to delete booking ${bookingID} for ${uid}`);
throw new Error(deleteResponse);
}
}
},
deleteUserSync: async ({borrowerID, branchID, uid}) => {
if (borrowerID !== undefined) {
try {
const {data} = await axios.delete(
`${loandisk.url}/${loandisk.publickey}/${branchID}/borrower/${borrowerID}`,
config
)
if (data.error) {
if (data.error.code === '404') {
console.warn(`[Warning] No Loandisk borrower found for ${uid}`);
return;
}
} else {
if (data.response === 'deleted') {
console.info(`[Success] Deleted Loandisk borrower for ${uid}`);
} else {
console.warn(`[Failure] Loandisk sent an unexpected response when trying to delete ${uid}`);
}
}
console.debug(`${data.response}`);
} catch (error) {
console.error('[Failure] An issue occured while communicating with Loandisk:', error.details);
}
}
try {
const userMetaRef = db.collection('appUserMeta');
await userMetaRef.doc(uid).delete()
console.info('[Success] Deleted user meta data');
} catch (error) {
console.log('[Failure] Error deleting user meta data', error);
}
try {
await admin.auth().deleteUser(uid)
console.info('[Success] Deleted user');
} catch (error) {
console.log('[Failure] Error deleting user', error);
}
},
resetWX40Loan: async () => {
try {
const { data } = await axios.put(
`${loandisk.url}/${loandisk.publickey}/${branchId}/loan/1469453`,
{
'loan_id': 1469453,
'loan_product_id': 55315,
'borrower_id': 1303604,
'loan_application_id': '1000063',
'loan_disbursed_by_id': 19412,
'loan_principal_amount': '15000.00',
'loan_released_date': '28/09/2021',
'loan_interest_method': 'flat_rate',
'loan_interest_type': 'percentage',
'loan_interest_period': 'Month',
'loan_interest': '1.5000',
'loan_duration_period': 'Months',
'loan_duration': 15,
'loan_payment_scheme_id': 3,
'loan_num_of_repayments': 15,
'loan_decimal_places': 'round_off_to_two_decimal',
'loan_interest_start_date': null,
'loan_fees_pro_rata': 0,
'loan_do_not_adjust_remaining_pro_rata': 0,
'loan_first_repayment_pro_rata': 0,
'loan_first_repayment_date': '07/11/2022',
'first_repayment_amount': '0.00',
'last_repayment_amount': '0.00',
'loan_override_maturity_date': null,
'override_each_repayment_amount': '0.00',
'loan_interest_each_repayment_pro_rata': null,
'loan_interest_schedule': 'charge_interest_normally',
'loan_principal_schedule': null,
'loan_balloon_repayment_amount': null,
'automatic_payments': 0,
'payment_posting_period': 0,
'total_amount_due': null,
'balance_amount': '18375.00',
'due_date': '07/01/2024',
'total_paid': '0.00',
'child_status_id': 18,
'loan_fee_schedule_2523': null,
'loan_fee_id_2523': 0,
'loan_override_sys_gen_penalty': 0,
'loan_manual_penalty_amount': '0.00',
'loan_status_id': 8,
'loan_title': null,
'loan_description': '',
'custom_field_1757': '33.8',
'custom_field_2422': '',
'custom_field_2423': '',
'custom_field_2424': '',
'custom_field_2425': '',
'custom_field_2439': '',
'custom_field_2864': '1500',
'custom_field_3190': '31/12/2022',
'custom_field_4447': '',
'custom_field_5319': '1500',
'custom_field_5355': '15000'
},
config
);
console.info(`[Success] Reset processing loan for WX444444(0)`);
} catch (error) {
console.log('[Failure] Error resetting processing loan for WX444444(0)', error);
}
},
updateUserMetaForUid: (user, forceSet) => {
if (forceSet === undefined) {
forceSet = false;
}
return updateUserMeta(user, forceSet).then(() => {
console.info(`[Success] User meta data updated for ${user.uid}`);
return true;
});
},
};
module.exports = testControl.run;