From edd444316232aeaabcbe470bb1a121e5a29fb2e5 Mon Sep 17 00:00:00 2001 From: Foromo Ernest Teoro Date: Thu, 7 Nov 2024 00:45:25 +0100 Subject: [PATCH 1/3] feat: unit test and integration test for stock supply activities --- .eslintrc | 3 + package.json | 2 +- src/add-feature.js | 10 +- src/features/stock-supply.js | 121 ++++++++++++++- test/mocks/mocks.js | 140 ++++++++++++++++++ .../translations/messages-en.properties | 18 +++ .../translations/messages-fr.properties | 19 +++ test/stock-count.spec.js | 20 +-- test/stock-discrepancy-feature.spec.js | 86 +++++++++++ test/stock-received-feature.spec.js | 76 ++++++++++ test/stock-supply-feature.spec.js | 74 +++++++++ test/stock-supply-integration.spec.js | 109 ++++++++++++++ test/test-utils.js | 82 +++++++++- 13 files changed, 734 insertions(+), 26 deletions(-) create mode 100644 test/stock-discrepancy-feature.spec.js create mode 100644 test/stock-received-feature.spec.js create mode 100644 test/stock-supply-feature.spec.js create mode 100644 test/stock-supply-integration.spec.js diff --git a/.eslintrc b/.eslintrc index 0a019e4..c493cbe 100644 --- a/.eslintrc +++ b/.eslintrc @@ -32,5 +32,8 @@ "SwitchCase": 1 } ] + }, + "globals": { + "jest": true } } \ No newline at end of file diff --git a/package.json b/package.json index 0ffb483..1a0fdd2 100644 --- a/package.json +++ b/package.json @@ -16,7 +16,7 @@ }, "scripts": { "cz": "cz", - "test": "jest", + "test": "jest --testTimeout=25000 --runInBand", "semantic-release": "semantic-release", "prepare": "husky" }, diff --git a/src/add-feature.js b/src/add-feature.js index 8819ffc..cbbfeae 100644 --- a/src/add-feature.js +++ b/src/add-feature.js @@ -44,7 +44,15 @@ async function selectFeature(configs) { choices: remainingFeatures.map((ft) => ({ name: FEATURES[ft], value: ft, - })) + })), + when: function (answers){ + const argv = process.argv; + if (!argv[4]){ + return true; + } + answers.name = argv[4]; + return false; + } } ]); diff --git a/src/features/stock-supply.js b/src/features/stock-supply.js index 62a4806..4e83404 100644 --- a/src/features/stock-supply.js +++ b/src/features/stock-supply.js @@ -448,19 +448,54 @@ async function getStockSupplyConfigs({ type: 'input', name: 'form_name', message: 'Enter stock supply form ID', - default: 'stock_supply' + default: 'stock_supply', + when: function(answers){ + const argv = process.argv; + if (!argv[4]){ + return true; + } + answers.form_name = argv[4]; + return false; + } }, ...languages.map((language) => ({ type: 'input', name: `title.${language}`, message: `Enter stock supply form title in ${language}`, - default: 'Stock Supply' + default: 'Stock Supply', + when: function(answers){ + const argv = process.argv; + if (!argv[5]){ + return true; + } + const answer = { + title: { + 'en':argv[5].split(',')[0], + 'fr':argv[5].split(',')[1], + } + }; + Object.assign(answers, answer); + return false; + } })), { type: 'confirm', name: 'confirm_supply.active', message: 'Activate supply confirmation', default: false, + when: function(answers){ + const argv = process.argv; + if (!argv[6]){ + return true; + } + const answer = { + confirm_supply: { + active: argv[6] + } + }; + Object.assign(answers, answer); + return false; + } } ]); @@ -470,25 +505,101 @@ async function getStockSupplyConfigs({ type: 'input', name: 'confirm_supply.form_name', message: 'Enter supply confirmation ID', - default: 'stock_received' + default: 'stock_received', + when: function(answers){ + const argv = process.argv; + if (!argv[7]){ + return true; + } + const answer = { + confirm_supply: { + form_name: argv[7] + } + }; + + Object.assign(answers, answer); + return false; + } }, ...languages.map((language) => ({ type: 'input', name: `confirm_supply.title.${language}`, message: `Enter supply confirmation form title in ${language}`, - default: 'Stock Received' + default: 'Stock Received', + when: function(answers){ + const argv = process.argv; + if (!argv[8]){ + return true; + } + const answer = { + confirm_supply: { + title: { + 'en':argv[8].split(',')[0], + 'fr':argv[8].split(',')[1], + } + } + }; + + Object.assign(answers, answer); + return false; + } })), { type: 'input', name: 'discrepancy.form_name', message: 'Enter discrepancy resolution form ID', default: 'stock_discrepancy_resolution', + when: function(answers){ + const argv = process.argv; + if (!argv[9]){ + return true; + } + const answer = { + discrepancy: { + form_name: argv[9] + } + }; + + Object.assign(answers, answer); + return false; + } }, ...languages.map((language) => ({ type: 'input', name: `discrepancy.title.${language}`, message: `Enter discrepancy resolution form title in ${language}`, - default: 'Stock Discrepancy Resolution' + default: 'Stock Discrepancy Resolution', + when: function(answers){ + const argv = process.argv; + if (!argv[10]){ + return true; + } + + const answer = { + form_name: argv[4], + title: { + 'en': argv[5].split(',')[0], + 'fr': argv[5].split(',')[1], + }, + discrepancy: { + form_name: argv[9], + title: { + 'en':argv[10].split(',')[0], + 'fr':argv[10].split(',')[1], + }, + }, + confirm_supply: { + form_name: argv[7], + title: { + 'en':argv[8].split(',')[0], + 'fr':argv[8].split(',')[1], + }, + active: argv[6] + } + }; + Object.assign(answers, answer); + return false; + } })) ]); confirmationConfigs['confirm_supply'].active = true; diff --git a/test/mocks/mocks.js b/test/mocks/mocks.js index e1c41e6..61581fd 100644 --- a/test/mocks/mocks.js +++ b/test/mocks/mocks.js @@ -1,4 +1,144 @@ module.exports = { + mockConfigsWithNoFeauture: { + features: { + no_feature: { + form_name: 'no_form' + }, + }, + }, + stockSupplyConfig: { + features: { + stock_supply: { + form_name: 'stock_supply', + title: { + en: 'Stock Supply', + fr: 'Livraison de Stock' + }, + confirm_supply: { + form_name: 'stock_received', + title: { + en: 'Stock Received', + fr: 'Réception de Stock' + }, + active: true + }, + discrepancy: { + form_name: 'stock_discrepancy_resolution', + title: { + en: 'Stock Discrepancy Resolution', + fr: 'Résolution de conflits' + } + } + }, + }, + levels: { + 1: { + contact_type: 'c62_chw', + role: 'chw', + place_type: 'c62_chw_site' + }, + 2: { + contact_type: 'c52_supervisor', + role: 'supervisor', + place_type: 'c50_supervision_area' + }, + }, + languages: ['en', 'fr'], + items: { + paracetamol: { + name: 'paracetamol', + label: { + en: 'Paracetamol', + fr: 'Paracetamole' + }, + isInSet: true, + set: { + label: { + en: 'Box of 8', + fr: 'Boite de 8' + }, + count: 8 + }, + unit: { + label: { + en: 'Tablet', + fr: 'Comprimes' + } + }, + warning_total: '20', + danger_total: '15', + max_total: '50', + category: 'malaria' + } + }, + categories: { + malaria: { + name: 'malaria', + label: { + fr: 'Malaria' + }, + description: { + fr: 'Malaria' + } + } + }, + useItemCategory: true, + defaultLanguage: 'fr', + }, + stockSupplyScenario: { + initScenario: [ + 'init', + '2_levels', + 'c62_chw', + 'chw', + 'c52_supervisor', + 'supervisor', + 'Y', + 'stock_count', + '[{contact_type: \'c62_chw\', role: \'chw\', place_type: \'c60_chw_site\' },{contact_type: \'c52_supervisor\',role: \'supervisor\',place_type: \'c50_supervision_area\'}]', + 'action', + 'end_of_week', + ['Stock count', 'Stock count'], + 'patient_assessment_under_5', + 'Y', + 'now()', + 'malaria', + ['Category', 'Categorie'], + ['Category', 'Categorie'], + 'paracetamol', + ['Paracetamol', 'Paracetamole'], + 'Y', + ['Box of 8', 'Boite de 8'], + 8, + ['Tablet', 'Comprimes'], + 20, + 15, + 15, + 'by_user', + 0 + ], + addStockSupplyFeature: [ + 'add', + 'feature', + 'stock_supply', + ['Stock Supply', 'Livraison de Stock'], + true, + 'stock_received', + ['Stock Received', 'Réception de Stock'], + 'stock_discrepancy_resolution', + ['Stock Discrepancy Resolution', 'Résolution de conflits'] + ], + productCategoryScenario: [ + 'malaria' + ], + productsScenario: [ + 'paracetamol___set', + 'paracetamol___unit', + 'paracetamol', + 'paracetamol___count' + ] + + }, stockCountScenario: { initScenario: [ 'init', diff --git a/test/project-config/translations/messages-en.properties b/test/project-config/translations/messages-en.properties index 5479131..98ca9f3 100644 --- a/test/project-config/translations/messages-en.properties +++ b/test/project-config/translations/messages-en.properties @@ -330,3 +330,21 @@ contact.child.mother.indicator.potable.water = Number of households with access contact.child.mother.indicator.cash.transfert = Number of households that have benefited from cash transfers contact.child.mother.indicator.sexual.mutilation = Number of children with sexual mutilations contact.child.mother.indicator.malnutrition = Number of children aged 6-59 months having been screened for malnutrition in a household + +cht-stock-monitoring-workflow.stock_supply.discrepancy.summary_header = Results/Summary page +cht-stock-monitoring-workflow.stock_supply.discrepancy.submit_note =

Be sure you Submit to complete this action.

+cht-stock-monitoring-workflow.stock_supply.discrepancy.summary_note = Discrepancy resolution +cht-stock-monitoring-workflow.stock_supply.discrepancy.quantity_issued = Quantity issued: {{qty}} +cht-stock-monitoring-workflow.stock_supply.discrepancy.quantity_confirmed = Quantity confirmed: {{qty}} +cht-stock-monitoring-workflow.stock_supply.discrepancy.quantity_final = What is the final quantity ? + +cht-stock-monitoring-workflow.stock_supply.page_1.header = Select item to supply +cht-stock-monitoring-workflow.stock_supply.forms.select_category = Select the category of what you want to return +cht-stock-monitoring-workflow.stock_supply.page_1.select_input = Select +cht-stock-monitoring-workflow.stock_supply.page_1.select_input_hint = Select all items to supply +cht-stock-monitoring-workflow.stock_supply.tasks.reception-confirmation = Stock received +cht-stock-monitoring-workflow.stock_supply.confirmation.item_received_confirmation_question = Did you received {{qty_unit}} +cht-stock-monitoring-workflow.stock_supply.confirmation.summary_note = Stock items you received. +cht-stock-monitoring-workflow.stock_supply.label.confirm_qty = Confirm quantities +cht-stock-monitoring-workflow.stock_supply.message.set_unit_constraint_message = Should be in the form x/y for x {{set_label}} and y {{unit_label}} +cht-stock-monitoring-workflow.stock_supply.message.unit_quantity_hint = Add the quantity: {{quantity}} {{unit_label}} diff --git a/test/project-config/translations/messages-fr.properties b/test/project-config/translations/messages-fr.properties index 7031adb..eca1ed7 100644 --- a/test/project-config/translations/messages-fr.properties +++ b/test/project-config/translations/messages-fr.properties @@ -465,3 +465,22 @@ contact.child.mother.indicator.potable.water = Nombre de ménage qui a accès à contact.child.mother.indicator.cash.transfert = Nombre de ménage qui recoit un cash transfert contact.child.mother.indicator.sexual.mutilation = Nombre d'enfant fille ayant subi une mutilation sexuelle contact.child.mother.indicator.malnutrition = Nombre d\'enfant de 6-59 mois ayant ete depiste de la malnutrition dans un menage + +cht-stock-monitoring-workflow.stock_supply.item.stock_on_hand = Stock actuel +cht-stock-monitoring-workflow.stock_supply.item.quantity_of = Quantité de +cht-stock-monitoring-workflow.stock_supply.summary_header = Page Résultats +cht-stock-monitoring-workflow.stock_supply.submit_note =

Assurez vous de soumettre pour enregistrer cette action.

+cht-stock-monitoring-workflow.stock_supply.summary_note = Stock livré. +cht-stock-monitoring-workflow.stock_supply.confirmation.item_received_question = Avez-vous reçu {{qty}} {{unit}} de {{item}} +cht-stock-monitoring-workflow.stock_supply.choices.yes_no.yes = Oui +cht-stock-monitoring-workflow.stock_supply.choices.yes_no.no = Non +cht-stock-monitoring-workflow.stock_supply.discrepancy.summary_header = Page Résultats +cht-stock-monitoring-workflow.stock_supply.discrepancy.submit_note =

Assurez-vous de soumettre pour compléter cette action.

+cht-stock-monitoring-workflow.stock_supply.discrepancy.summary_note = Résolution de conflits +cht-stock-monitoring-workflow.stock_supply.discrepancy.quantity_issued = Quantité envoyée : {{qty}} +cht-stock-monitoring-workflow.stock_supply.discrepancy.quantity_confirmed = Quantité confirmée : {{qty}} +cht-stock-monitoring-workflow.stock_supply.discrepancy.quantity_final = Quelle est la quantité finale ? + +cht-stock-monitoring-workflow.stock_supply.message.set_unit_constraint_message = Doit étre sous la forme x/y pour x {{set_label}} et y {{unit_label}} +cht-stock-monitoring-workflow.stock_supply.message.unit_quantity_hint = Ajouter quantité : {{quantity}} {{unit_label}} +cht-stock-monitoring-workflow.stock_supply.confirmation.item_received_confirmation_question = Avez-vous reçu {{qty_unit}} diff --git a/test/stock-count.spec.js b/test/stock-count.spec.js index 839bdf2..082c04a 100644 --- a/test/stock-count.spec.js +++ b/test/stock-count.spec.js @@ -12,13 +12,14 @@ const { describe('Stock count', () => { + const workingDir = process.cwd(); beforeEach(() => { setDirToprojectConfig(); }); afterEach(() => { - revertBackToProjectHome(process.cwd()); + revertBackToProjectHome(workingDir); }); it('Add stock count summaries test', async() => { @@ -71,23 +72,6 @@ describe('Stock count', () => { expect(fs.unlinkSync(stockMonitoringConfig)).toBe(undefined); expect(fs.unlinkSync(formPath)).toBe(undefined); expect(fs.unlinkSync(formPropertiesPath)).toBe(undefined); - - const translationFiles = fs.readdirSync(path.join(processDir, 'translations')); - for(const translationFile of translationFiles){ - - const messageFileContent = fs.readFileSync(path.join(processDir, 'translations', translationFile), {encoding: 'utf-8'}); - expect(messageFileContent).not.toBe(''); - const newMessageContent = messageFileContent.split('\n').map(message => { - if(!message.toString().includes('cht-stock-monitoring-workflow') && message.toString()!==''){ - return `${message.toString()}\n`; - } - }); - - expect(newMessageContent.includes('cht-stock-monitoring-workflow')).toBe(false); - fs.truncate(path.join(processDir, 'translations', translationFile), 0, function () {}); - fs.writeFile(path.join(processDir, 'translations', translationFile),newMessageContent.toString().replaceAll(',', '')); - - } }); }); diff --git a/test/stock-discrepancy-feature.spec.js b/test/stock-discrepancy-feature.spec.js new file mode 100644 index 0000000..77d5a31 --- /dev/null +++ b/test/stock-discrepancy-feature.spec.js @@ -0,0 +1,86 @@ +const fs = require('fs'); +const path = require('path'); +const { stockSupplyConfig, mockConfigsWithNoFeauture } = require('./mocks/mocks'); +const { updateStockDiscrepancy } = require('../src/features/stock-discrepancy'); +const { + setDirToprojectConfig, + revertBackToProjectHome, + readOutputFiles, + cleanUp +} = require('./test-utils'); + +describe('update Stock Supply', () => { + const workingDir = process.cwd(); + const createdAppFormFiles = ['stock_discrepancy_resolution.xlsx', 'stock_discrepancy_resolution.properties.json']; + + beforeEach(() => { + setDirToprojectConfig(); + }); + + afterEach(async() => { + // Remove the generated files + await cleanUp(workingDir, createdAppFormFiles); + revertBackToProjectHome(workingDir); + jest.clearAllMocks(); + }); + + it('stock return form should should not be generated and updated', async () => { + const projectDataDir = process.cwd(); + // Check that stock discrepancy xlsx and properties files does not exist. + for(const createdAppFormFile of createdAppFormFiles){ + expect(fs.existsSync(path.join(projectDataDir, 'forms', 'app', createdAppFormFile))).toBe(false); + } + + // Call the function updateStockDiscrepancy and check it throws an exception when there is no match config + await expect( updateStockDiscrepancy(mockConfigsWithNoFeauture)).rejects.toThrow(Error); + + }); + + + it('should update the stock supply form with correct values', async () => { + const processDir = process.cwd(); + + // Check that stock confirmation xlsx and properties files exist. + for(const createdAppFormFile of createdAppFormFiles){ + expect(fs.existsSync(path.join(processDir, 'forms', 'app', createdAppFormFile))).toBe(false); + } + // Call the function updateStockDiscrepancy and check that the stock_received files are generated + await updateStockDiscrepancy(stockSupplyConfig); + + for(const createdAppFormFile of createdAppFormFiles){ + expect(fs.existsSync(path.join(processDir, 'forms', 'app', createdAppFormFile))).toBe(true); + } + + // Check that stock received files content are correctly written. + const {workbook, propertiesFileContent} = await readOutputFiles(createdAppFormFiles); + const spy = jest.spyOn(workbook, 'getWorksheet'); + const surveyWorkSheet = workbook.getWorksheet('survey'); + expect(spy).toHaveBeenCalledTimes(1); + const settingWorkSheet = workbook.getWorksheet('settings'); + expect(spy).toHaveBeenCalledTimes(2); + expect(surveyWorkSheet._name).toEqual('survey'); + expect(settingWorkSheet._name).toEqual('settings'); + expect(surveyWorkSheet).not.toEqual([]); + expect(settingWorkSheet).not.toEqual([]); + + expect(JSON.parse(propertiesFileContent)).toEqual({ + 'context': { + 'expression': 'user.parent.contact_type === \'c50_supervision_area\' && user.role === \'supervisor\'', + 'person': false, + 'place': false + }, + 'icon': 'icon-healthcare-medicine', + 'title': [ + { + 'content': 'Stock Discrepancy Resolution', + 'locale': 'en' + }, + { + 'content': 'Résolution de conflits', + 'locale': 'fr' + } + ] + }); + + }); +}); diff --git a/test/stock-received-feature.spec.js b/test/stock-received-feature.spec.js new file mode 100644 index 0000000..c71405f --- /dev/null +++ b/test/stock-received-feature.spec.js @@ -0,0 +1,76 @@ +const fs = require('fs'); +const path = require('path'); +const { stockSupplyConfig } = require('./mocks/mocks'); +const { updateStockConfirmation } = require('../src/features/stock-received'); +const { getTranslations } = require('../src/common'); +const { + setDirToprojectConfig, + revertBackToProjectHome, + readOutputFiles, + cleanUp +} = require('./test-utils'); + +describe('update Stock Supply', () => { + const workingDir = process.cwd(); + const createdAppFormFiles = ['stock_received.xlsx', 'stock_received.properties.json']; + + beforeEach(() => { + setDirToprojectConfig(); + }); + + afterEach(async () => { + // Remove the generated files + await cleanUp(workingDir, createdAppFormFiles); + revertBackToProjectHome(workingDir); + jest.clearAllMocks(); + }); + + it('should update the stock supply form with correct values', async () => { + const processDir = process.cwd(); + + // Check that stock confirmation xlsx and properties files exist. + for(const createdAppFormFile of createdAppFormFiles){ + expect(fs.existsSync(path.join(processDir, 'forms', 'app', createdAppFormFile))).toBe(false); + } + // Call the function updateStockConfirmation and check that the stock_received files are generated + const messages = getTranslations(); + expect(messages.length).not.toEqual(0); + await updateStockConfirmation(stockSupplyConfig, messages); + + for(const createdAppFormFile of createdAppFormFiles){ + expect(fs.existsSync(path.join(processDir, 'forms', 'app', createdAppFormFile))).toBe(true); + } + + // Check that stock received files content are correctly written. + const {workbook, propertiesFileContent} = await readOutputFiles(createdAppFormFiles); + const spy = jest.spyOn(workbook, 'getWorksheet'); + const surveyWorkSheet = workbook.getWorksheet('survey'); + expect(spy).toHaveBeenCalledTimes(1); + const settingWorkSheet = workbook.getWorksheet('settings'); + expect(spy).toHaveBeenCalledTimes(2); + expect(surveyWorkSheet._name).toEqual('survey'); + expect(settingWorkSheet._name).toEqual('settings'); + expect(surveyWorkSheet).not.toEqual([]); + expect(settingWorkSheet).not.toEqual([]); + + expect(JSON.parse(propertiesFileContent)).toEqual({ + 'context': { + 'expression': 'user.parent.contact_type === \'c62_chw_site\'', + 'person': false, + 'place': false + }, + 'icon': 'icon-healthcare-medicine', + 'title': [ + { + 'content': 'Stock Received', + 'locale': 'en' + }, + { + 'content': 'Réception de Stock', + 'locale': 'fr' + } + ] + }); + + }); +}); diff --git a/test/stock-supply-feature.spec.js b/test/stock-supply-feature.spec.js new file mode 100644 index 0000000..d7f40f6 --- /dev/null +++ b/test/stock-supply-feature.spec.js @@ -0,0 +1,74 @@ +const fs = require('fs'); +const path = require('path'); +const { stockSupplyConfig } = require('./mocks/mocks'); +const { updateStockSupply } = require('../src/features/stock-supply'); +const { + setDirToprojectConfig, + revertBackToProjectHome, + readOutputFiles, + cleanUp +} = require('./test-utils'); + +describe('update Stock Supply', () => { + const workingDir = process.cwd(); + const createdAppFormFiles = ['stock_supply.xlsx', 'stock_supply.properties.json']; + + beforeEach(() => { + setDirToprojectConfig(); + }); + + afterEach(async () => { + // Remove the generated files + await cleanUp(workingDir, createdAppFormFiles); + revertBackToProjectHome(workingDir); + jest.clearAllMocks(); + }); + + + it('should update the stock supply form with correct values', async () => { + const processDir = process.cwd(); + + // Check that stock supply xlsx and properties files exist. + for(const createdAppFormFile of createdAppFormFiles){ + expect(fs.existsSync(path.join(processDir, 'forms', 'app', createdAppFormFile))).toBe(false); + } + // Call the function updateStockSupply and check that the stock_supply files are generated + await updateStockSupply(stockSupplyConfig); + + for(const createdAppFormFile of createdAppFormFiles){ + expect(fs.existsSync(path.join(processDir, 'forms', 'app', createdAppFormFile))).toBe(true); + } + + // Check that stock supply files content are correctly written. + const {workbook, propertiesFileContent} = await readOutputFiles(createdAppFormFiles); + const spy = jest.spyOn(workbook, 'getWorksheet'); + const surveyWorkSheet = workbook.getWorksheet('survey'); + expect(spy).toHaveBeenCalledTimes(1); + const settingWorkSheet = workbook.getWorksheet('settings'); + expect(spy).toHaveBeenCalledTimes(2); + expect(surveyWorkSheet._name).toEqual('survey'); + expect(settingWorkSheet._name).toEqual('settings'); + expect(surveyWorkSheet).not.toEqual([]); + expect(settingWorkSheet).not.toEqual([]); + + expect(JSON.parse(propertiesFileContent)).toEqual({ + 'context': { + 'expression': 'contact.contact_type === \'c62_chw_site\' && user.parent.contact_type === \'c50_supervision_area\' && user.role === \'supervisor\'', + 'person': false, + 'place': true + }, + 'icon': 'icon-healthcare-medicine', + 'title': [ + { + 'content': 'Stock Supply', + 'locale': 'en' + }, + { + 'content': 'Livraison de Stock', + 'locale': 'fr' + } + ] + }); + + }); +}); diff --git a/test/stock-supply-integration.spec.js b/test/stock-supply-integration.spec.js new file mode 100644 index 0000000..cea2e4d --- /dev/null +++ b/test/stock-supply-integration.spec.js @@ -0,0 +1,109 @@ +const { spawnSync } = require('child_process'); +const path = require('path'); +const fs = require('fs-extra'); + +const { + stockSupplyScenario, + stockCountScenario +} = require('./mocks/mocks'); +const { + setDirToprojectConfig, + revertBackToProjectHome, + cleanUp, + readOutputFiles, + readDataFromXforms +} = require('./test-utils'); + + +describe('Stock supply integration test', () => { + const workingDir = process.cwd(); + const createdAppFormFiles = [ 'stock_count.xlsx', 'stock_count.properties.json', 'stock_supply.xlsx', 'stock_supply.properties.json', 'stock_received.xlsx', 'stock_received.properties.json', 'stock_discrepancy_resolution.xlsx', 'stock_discrepancy_resolution.properties.json']; + + beforeEach(() => { + setDirToprojectConfig(); + }); + + afterEach(async() => { + // Remove the generated files + await cleanUp(workingDir, createdAppFormFiles); + revertBackToProjectHome(workingDir); + jest.clearAllMocks(); + }); + + it('Add stock out integration test', async() => { + const processDir = process.cwd(); + // Check that stock supply, received and stock discrepancy xform and properties files are not generated + for(const createdAppFormFile of createdAppFormFiles){ + expect(fs.existsSync(path.join(processDir, 'forms', 'app', createdAppFormFile))).toBe(false); + } + + // Initializing stock monitoring + const childProcess = await spawnSync('../../main.js', stockSupplyScenario.initScenario); + + if (childProcess.error) { + throw childProcess.error; + } + else { + + // Add stock supply feature test + const stockSupplyChildProcess = await spawnSync('../../main.js', stockSupplyScenario.addStockSupplyFeature); + if (stockSupplyChildProcess.error) { + throw stockSupplyChildProcess.error; + } + else { + + // Check that stock monitoring is initialized and stock count and stock out xform and properties files are generated + for(const createdAppFormFile of createdAppFormFiles){ + expect(fs.existsSync(path.join(processDir, 'forms', 'app', createdAppFormFile))).toBe(true); + } + + expect(fs.existsSync(path.join(processDir, 'stock-monitoring.config.json'))).toBe(true); + + // Check that stock count files content are correctly written. + const {workbook, propertiesFileContent} = await readOutputFiles(['stock_count.xlsx', 'stock_count.properties.json']); + let surveyWorkSheet = workbook.getWorksheet('survey'); + let settingWorkSheet = workbook.getWorksheet('settings'); + expect(surveyWorkSheet._name).toEqual('survey'); + expect(settingWorkSheet._name).toEqual('settings'); + expect(propertiesFileContent).not.toEqual([]); + + // Check that the products are available in stock count xform + const {productsList, productCategoryList} = await readDataFromXforms(stockCountScenario.productCategoryScenario, stockCountScenario.productsScenario, 'stock_count.xlsx'); + expect(productCategoryList.length).toBe(stockCountScenario.productCategoryScenario.length); + expect(productCategoryList.entries).toStrictEqual(stockCountScenario.productCategoryScenario.entries); + + expect(productsList.length).toBe(stockCountScenario.productsScenario.length); + expect(productsList.entries).toStrictEqual(stockCountScenario.productsScenario.entries); + + // Check that stock Supply files content are correctly written. + const stockSupplyWorkbook = await readOutputFiles(['stock_supply.xlsx', 'stock_supply.properties.json']); + surveyWorkSheet = stockSupplyWorkbook.workbook.getWorksheet('survey'); + settingWorkSheet = stockSupplyWorkbook.workbook.getWorksheet('settings'); + expect(surveyWorkSheet._name).toEqual('survey'); + expect(settingWorkSheet._name).toEqual('settings'); + expect(stockSupplyWorkbook.propertiesFileContent).not.toEqual([]); + + // Check that stock Received files content are correctly written. + const stockReceivedWorkbook = await readOutputFiles(['stock_supply.xlsx', 'stock_supply.properties.json']); + surveyWorkSheet = stockReceivedWorkbook.workbook.getWorksheet('survey'); + settingWorkSheet = stockReceivedWorkbook.workbook.getWorksheet('settings'); + expect(surveyWorkSheet._name).toEqual('survey'); + expect(settingWorkSheet._name).toEqual('settings'); + expect(stockReceivedWorkbook.propertiesFileContent).not.toEqual([]); + + // Check that stock Discrepancy files content are correctly written. + const stockDiscrepancyWorkbook = await readOutputFiles(['stock_discrepancy_resolution.xlsx', 'stock_discrepancy_resolution.properties.json']); + surveyWorkSheet = stockDiscrepancyWorkbook.workbook.getWorksheet('survey'); + settingWorkSheet = stockDiscrepancyWorkbook.workbook.getWorksheet('settings'); + expect(surveyWorkSheet._name).toEqual('survey'); + expect(settingWorkSheet._name).toEqual('settings'); + expect(stockDiscrepancyWorkbook.propertiesFileContent).not.toEqual([]); + + } + } + + }); + +}); + + diff --git a/test/test-utils.js b/test/test-utils.js index a7cf32e..14049b2 100644 --- a/test/test-utils.js +++ b/test/test-utils.js @@ -1,5 +1,7 @@ const process = require('process'); const path = require('path'); +const ExcelJS = require('exceljs'); +const fs = require('fs'); const currentWorkingDirectory = () =>{ return process.cwd(); @@ -14,10 +16,88 @@ const revertBackToProjectHome = (projectHome) =>{ process.chdir(projectHome); }; +const readDataFromXforms = async (productCategoryScenario, productsScenario, fileName) => { + const projectPath = process.cwd(); + const productCategoryList = []; + const productsList = []; + + const workbook = new ExcelJS.Workbook(); + const xlsx = workbook.xlsx; + await xlsx.readFile(path.join(projectPath, 'forms', 'app', fileName)); + const surveyWorkSheet = workbook.getWorksheet('survey'); + const nameCol = surveyWorkSheet.getColumn('B'); + let productIndex = 0; + let productCatIndex =0; + nameCol.eachCell(function(cell){ + + if(productCategoryScenario !== undefined && productCategoryScenario.length > 0){ + if(cell.value === productCategoryScenario[productCatIndex] && productCatIndex < productCategoryScenario.length){ + productCategoryList.push(cell.value); + productCatIndex ++; + productIndex = 0; + } + } + + if(productsScenario !== undefined && productsScenario.length > 0){ + if(cell.value === productsScenario[productIndex] && productIndex < productsScenario.length){ + productsList.push(cell.value); + productIndex ++; + } + } + }); + + return { + productsList, + productCategoryList + }; + +}; + +const cleanUp = async (workingDir, createdAppFormFiles) => { + const processDir = path.join(workingDir,'test/project-config/'); + for(const createdAppFormFile of createdAppFormFiles){ + const filePath = path.join(processDir, 'forms', 'app', createdAppFormFile); + fs.stat(filePath, (error) => { + if (!error) { + fs.unlinkSync(filePath); + } + }); + } + + // Removing the stock monitoring init file and stock count file + const stockMonitoringInitPath = path.join(processDir, 'stock-monitoring.config.json'); + fs.stat(stockMonitoringInitPath, (error) => { + if (!error) { + fs.unlinkSync(stockMonitoringInitPath); + } + }); + +}; + +const readOutputFiles = async (filesNames) => { + const projectPath = process.cwd(); + const formPath = path.join(projectPath, 'forms', 'app', filesNames[0]); + const workbook = new ExcelJS.Workbook(); + await workbook.xlsx.readFile(formPath); + const propertiesFileContent = fs.readFileSync( + path.join(projectPath, 'forms', 'app', filesNames[1]), + {encoding: 'utf-8'} + ); + + return { + workbook, + propertiesFileContent + }; + +}; + module.exports = { setDirToprojectConfig, currentWorkingDirectory, - revertBackToProjectHome + revertBackToProjectHome, + cleanUp, + readOutputFiles, + readDataFromXforms }; From ef016210796f58f50f5a11974c1b463fcf23e32a Mon Sep 17 00:00:00 2001 From: Foromo Ernest Teoro Date: Thu, 7 Nov 2024 01:28:30 +0100 Subject: [PATCH 2/3] feat: add no feature config scenario --- test/stock-discrepancy-feature.spec.js | 6 +++--- test/stock-received-feature.spec.js | 19 ++++++++++++++++--- test/stock-supply-feature.spec.js | 15 +++++++++++++-- 3 files changed, 32 insertions(+), 8 deletions(-) diff --git a/test/stock-discrepancy-feature.spec.js b/test/stock-discrepancy-feature.spec.js index 77d5a31..4110d77 100644 --- a/test/stock-discrepancy-feature.spec.js +++ b/test/stock-discrepancy-feature.spec.js @@ -9,7 +9,7 @@ const { cleanUp } = require('./test-utils'); -describe('update Stock Supply', () => { +describe('update Stock Discrepancy', () => { const workingDir = process.cwd(); const createdAppFormFiles = ['stock_discrepancy_resolution.xlsx', 'stock_discrepancy_resolution.properties.json']; @@ -24,7 +24,7 @@ describe('update Stock Supply', () => { jest.clearAllMocks(); }); - it('stock return form should should not be generated and updated', async () => { + it('should not be generated and updated stock discrepancy form', async () => { const projectDataDir = process.cwd(); // Check that stock discrepancy xlsx and properties files does not exist. for(const createdAppFormFile of createdAppFormFiles){ @@ -37,7 +37,7 @@ describe('update Stock Supply', () => { }); - it('should update the stock supply form with correct values', async () => { + it('should update the stock discrepancy form with correct values', async () => { const processDir = process.cwd(); // Check that stock confirmation xlsx and properties files exist. diff --git a/test/stock-received-feature.spec.js b/test/stock-received-feature.spec.js index c71405f..27421b3 100644 --- a/test/stock-received-feature.spec.js +++ b/test/stock-received-feature.spec.js @@ -1,6 +1,6 @@ const fs = require('fs'); const path = require('path'); -const { stockSupplyConfig } = require('./mocks/mocks'); +const { stockSupplyConfig, mockConfigsWithNoFeauture } = require('./mocks/mocks'); const { updateStockConfirmation } = require('../src/features/stock-received'); const { getTranslations } = require('../src/common'); const { @@ -10,7 +10,7 @@ const { cleanUp } = require('./test-utils'); -describe('update Stock Supply', () => { +describe('update Stock Received', () => { const workingDir = process.cwd(); const createdAppFormFiles = ['stock_received.xlsx', 'stock_received.properties.json']; @@ -25,7 +25,20 @@ describe('update Stock Supply', () => { jest.clearAllMocks(); }); - it('should update the stock supply form with correct values', async () => { + + it('should not be generated and updated stock received form', async () => { + const projectDataDir = process.cwd(); + // Check that stock discrepancy xlsx and properties files does not exist. + for(const createdAppFormFile of createdAppFormFiles){ + expect(fs.existsSync(path.join(projectDataDir, 'forms', 'app', createdAppFormFile))).toBe(false); + } + + // Call the function updateStockDiscrepancy and check it throws an exception when there is no match config + await expect( updateStockConfirmation(mockConfigsWithNoFeauture)).rejects.toThrow(Error); + + }); + + it('should update the stock received form with correct values', async () => { const processDir = process.cwd(); // Check that stock confirmation xlsx and properties files exist. diff --git a/test/stock-supply-feature.spec.js b/test/stock-supply-feature.spec.js index d7f40f6..70e6deb 100644 --- a/test/stock-supply-feature.spec.js +++ b/test/stock-supply-feature.spec.js @@ -1,6 +1,6 @@ const fs = require('fs'); const path = require('path'); -const { stockSupplyConfig } = require('./mocks/mocks'); +const { stockSupplyConfig, mockConfigsWithNoFeauture } = require('./mocks/mocks'); const { updateStockSupply } = require('../src/features/stock-supply'); const { setDirToprojectConfig, @@ -24,8 +24,19 @@ describe('update Stock Supply', () => { jest.clearAllMocks(); }); + it('should not generate and update stock supply form', async () => { + const projectDataDir = process.cwd(); + // Check that stock discrepancy xlsx and properties files does not exist. + for(const createdAppFormFile of createdAppFormFiles){ + expect(fs.existsSync(path.join(projectDataDir, 'forms', 'app', createdAppFormFile))).toBe(false); + } + + // Call the function updateStockDiscrepancy and check it throws an exception when there is no match config + await expect( updateStockSupply(mockConfigsWithNoFeauture)).rejects.toThrow(Error); + + }); - it('should update the stock supply form with correct values', async () => { + it('should generate and update the stock supply form with correct values', async () => { const processDir = process.cwd(); // Check that stock supply xlsx and properties files exist. From e753242bf49aece1b731a2a68ade3c7a14cc2d2f Mon Sep 17 00:00:00 2001 From: Foromo Ernest Teoro Date: Fri, 29 Nov 2024 00:03:18 +0100 Subject: [PATCH 3/3] fix: feedback and code cleanup --- src/features/stock-discrepancy.js | 6 +- src/features/stock-received.js | 4 + src/features/stock-supply.js | 4 + test/mocks/mocks.js | 119 ++++++-- test/stock-count.spec.js | 6 +- ...tock-discrepancy-feature-functions.spec.js | 252 ++++++++++++++++ test/stock-discrepancy-feature.spec.js | 65 ++++- test/stock-out-feature-functions.spec.js | 10 +- test/stock-out-feature.spec.js | 4 +- test/stock-out-integration.spec.js | 6 +- test/stock-received-feature-functions.spec.js | 234 +++++++++++++++ test/stock-received-feature.spec.js | 63 +++- test/stock-supply-feature-functions.spec.js | 270 ++++++++++++++++++ test/stock-supply-feature.spec.js | 70 ++++- test/stock-supply-integration.spec.js | 103 +++++-- test/test-utils.js | 2 +- 16 files changed, 1150 insertions(+), 68 deletions(-) create mode 100644 test/stock-discrepancy-feature-functions.spec.js create mode 100644 test/stock-received-feature-functions.spec.js create mode 100644 test/stock-supply-feature-functions.spec.js diff --git a/src/features/stock-discrepancy.js b/src/features/stock-discrepancy.js index f448241..b77ad65 100644 --- a/src/features/stock-discrepancy.js +++ b/src/features/stock-discrepancy.js @@ -478,5 +478,9 @@ async function updateStockDiscrepancy(configs) { } module.exports = { - updateStockDiscrepancy + updateStockDiscrepancy, + getSummaries, + getItemRows, + getExportCalculations, + getAdditionalDoc }; diff --git a/src/features/stock-received.js b/src/features/stock-received.js index 03fbdb3..1e9d1c5 100644 --- a/src/features/stock-received.js +++ b/src/features/stock-received.js @@ -393,4 +393,8 @@ async function updateStockConfirmation(configs, messages) { module.exports = { updateStockConfirmation, + getItemRows, + addStockConfirmCalculation, + addStockConfirmSummaries, + getLabelColumns }; diff --git a/src/features/stock-supply.js b/src/features/stock-supply.js index 4e83404..a8051dc 100644 --- a/src/features/stock-supply.js +++ b/src/features/stock-supply.js @@ -615,4 +615,8 @@ async function getStockSupplyConfigs({ module.exports = { updateStockSupply, getStockSupplyConfigs, + addStockSupplyCalculation, + getItemRows, + getAdditionalDoc, + addStockSupplySummaries }; diff --git a/test/mocks/mocks.js b/test/mocks/mocks.js index 08a48d7..1356f9f 100644 --- a/test/mocks/mocks.js +++ b/test/mocks/mocks.js @@ -6,7 +6,7 @@ module.exports = { }, }, }, - stockOutMockConfigs: { + stockMonitoringConfigs: { features: { stock_out: { form_name: 'stock_out', @@ -16,6 +16,63 @@ module.exports = { fr: 'Titre du Stock' }, }, + stock_return: { + form_name: 'stock_return', + title: { + en: 'Stock Return', + fr: 'Retour de Stock' + }, + confirmation: { + form_name: 'stock_returned', + title: { + en: 'Stock Returned', + fr: 'Stock Retourné' + }, + } + }, + stock_order: { + actors: [ + { + contact_type: 'c62_chw', + role: 'chw', + place_type: 'c60_chw_site' + } + ], + form_name: 'stock_order', + title: { + en: 'Stock Order', + fr: 'Commande de Stock' + }, + stock_supply: { + form_name: 'stock_order_supply', + title: { + en: 'Stock Order Supply', + fr: 'Livraison de Commande de Stock' + } + } + }, + stock_supply: { + form_name: 'stock_supply', + title: { + en: 'Stock Supply', + fr: 'Livraison de Stock' + }, + confirm_supply: { + form_name: 'stock_received', + title: { + en: 'Stock Received', + fr: 'Réception de Stock' + }, + active: true + }, + discrepancy: { + form_name: 'stock_discrepancy_resolution', + title: { + en: 'Stock Discrepancy Resolution', + fr: 'Résolution de conflits' + } + } + }, }, levels: { 1: { @@ -71,8 +128,7 @@ module.exports = { useItemCategory: true, defaultLanguage: 'fr', }, - - stockOutScenario: { + stockMonitoringScenario: { initScenario: [ 'init', '2_levels', @@ -104,15 +160,6 @@ module.exports = { 'by_user', 0, ], - addStockOutFeatureScenario: [ - 'add', 'feature', 'stock_out', 'stock_out', 'item_danger_qty', ['Stock Out', 'Stock Out'] - ], - productsScenario: [ - 'paracetamol_at_hand___set', - 'paracetamol_at_hand___unit', - 'paracetamol_required___set', - 'paracetamol_required___unit' - ], invalidCommandInitScenario: [ 'test', '2_levels', @@ -144,15 +191,46 @@ module.exports = { 'by_user', 0, ], - invalidAddStockOutFeatureScenario: [ + invalidFeatureCommandScenario: [ 'minus', 'data', 'stock_out', 'stock_out', 'item_danger_qty', ['Stock Out', 'Stock Out'] ], + }, + stockSupplyScenario: { + addStockSupplyFeature: [ + 'add', + 'feature', + 'stock_supply', + ['Stock Supply', 'Livraison de Stock'], + true, + 'stock_received', + ['Stock Received', 'Réception de Stock'], + 'stock_discrepancy_resolution', + ['Stock Discrepancy Resolution', 'Résolution de conflits'] + ], + productCategoryScenario: [ + 'malaria' + ], + productsScenario: [ + 'paracetamol___set', + 'paracetamol___unit', + 'paracetamol', + 'paracetamol___count' + ] }, - stockCountScenario: { - initScenario: [ - 'init', + stockOutScenario: { + addStockOutFeatureScenario: [ + 'add', 'feature', 'stock_out', 'stock_out', 'item_danger_qty', ['Stock Out', 'Stock Out'] + ], + productsScenario: [ + 'paracetamol_at_hand___set', + 'paracetamol_at_hand___unit', + 'paracetamol_required___set', + 'paracetamol_required___unit' + ], + invalidCommandInitScenario: [ + 'test', '2_levels', 'c62_chw', 'chw', @@ -180,8 +258,15 @@ module.exports = { 15, 15, 'by_user', - 0 + 0, ], + invalidAddStockOutFeatureScenario: [ + 'minus', 'data', 'stock_out', 'stock_out', 'item_danger_qty', ['Stock Out', 'Stock Out'] + ], + + }, + + stockCountScenario: { productCategoryScenario: [ 'malaria' ], diff --git a/test/stock-count.spec.js b/test/stock-count.spec.js index eee8a0a..b5c193b 100644 --- a/test/stock-count.spec.js +++ b/test/stock-count.spec.js @@ -2,7 +2,7 @@ const { spawnSync } = require('child_process'); const path = require('path'); const fs = require('fs-extra'); -const { stockCountScenario, stockOutScenario } = require('./mocks/mocks'); +const { stockMonitoringScenario, stockCountScenario, stockOutScenario } = require('./mocks/mocks'); const { setDirToprojectConfig, revertBackToProjectHome, @@ -44,7 +44,7 @@ describe('Create and update stock_count.xlsx and properties files', () => { afterEach(async() => { await resetTranslationMessages(process.cwd()); - cleanUp(workingDir, createdAppFormFiles); + await cleanUp(workingDir, createdAppFormFiles); revertBackToProjectHome(workingDir); }); @@ -85,7 +85,7 @@ describe('Create and update stock_count.xlsx and properties files', () => { expect(fs.existsSync(path.join(processDir, 'forms', 'app', createdAppFormFile))).toBe(false); } - const childProcess = spawnSync('../../main.js', stockCountScenario.initScenario); + const childProcess = spawnSync('../../main.js', stockMonitoringScenario.initScenario); if (childProcess.error) { throw childProcess.error; diff --git a/test/stock-discrepancy-feature-functions.spec.js b/test/stock-discrepancy-feature-functions.spec.js new file mode 100644 index 0000000..ce9af4e --- /dev/null +++ b/test/stock-discrepancy-feature-functions.spec.js @@ -0,0 +1,252 @@ +const { + stockMonitoringConfigs +} = require('./mocks/mocks'); + +const { + getItemRows, + getExportCalculations, + getAdditionalDoc, + getSummaries, +} = require('../src/features/stock-discrepancy'); + +const { + setDirToprojectConfig, + revertBackToProjectHome, + writeTranslationMessages, + resetTranslationMessages, +} = require('./test-utils'); + +const { getTranslations } = require('../src/common'); + +describe('Testing functions in Stock out feature file', () => { + const processInitialArgv = process.argv; // Save the original argv + const workingDir = process.cwd(); + const enMessage = 'cht-stock-monitoring-workflow.stock_supply.page_1.header = Select item to supply\ncht-stock-monitoring-workflow.stock_supply.forms.select_category = Select the category of what you want to return\n' + +'cht-stock-monitoring-workflow.stock_supply.page_1.select_input = Select\ncht-stock-monitoring-workflow.stock_supply.page_1.select_input_hint = Select all items to supply\ncht-stock-monitoring-workflow.stock_supply.item.stock_on_hand = Stock on hand\ncht-stock-monitoring-workflow.stock_supply.item.quantity_of = Quantity of\n' + +'cht-stock-monitoring-workflow.stock_supply.summary_header = Results/Summary page\ncht-stock-monitoring-workflow.stock_supply.submit_note =

Be sure you Submit to complete this action.

\n' + +'cht-stock-monitoring-workflow.stock_supply.summary_note = Stock items you supply.\ncht-stock-monitoring-workflow.stock_supply.tasks.reception-confirmation = Stock received\n' + +'cht-stock-monitoring-workflow.stock_supply.confirmation.item_received_confirmation_question = Did you received {{qty_unit}}\ncht-stock-monitoring-workflow.stock_supply.choices.yes_no.yes = Yes\n' + +'cht-stock-monitoring-workflow.stock_supply.choices.yes_no.no = No\ncht-stock-monitoring-workflow.stock_supply.forms.additional_doc_title = Stock uses\ncht-stock-monitoring-workflow.stock_supply.forms.item_used_question = Quantity of {{item}}\n' + +'cht-stock-monitoring-workflow.stock_supply.confirmation.qty_received_question = Enter the quantity received\ncht-stock-monitoring-workflow.stock_supply.tasks.stock-descreptancy = Commodity Discrepancy Resolution\n' + +'cht-stock-monitoring-workflow.stock_supply.forms.select_items = Select the different item you want to supply\ncht-stock-monitoring-workflow.stock_supply.confirmation.summary_note = Stock items you received.\n' + +'cht-stock-monitoring-workflow.stock_supply.discrepancy.summary_header = Results/Summary page\ncht-stock-monitoring-workflow.stock_supply.discrepancy.submit_note =

Be sure you Submit to complete this action.

\n' + +'cht-stock-monitoring-workflow.stock_supply.discrepancy.summary_note = Discrepancy resolution\ncht-stock-monitoring-workflow.stock_supply.discrepancy.quantity_issued = Quantity issued: {{qty}}\n' + +'cht-stock-monitoring-workflow.stock_supply.discrepancy.quantity_confirmed = Quantity confirmed: {{qty}}\ncht-stock-monitoring-workflow.stock_supply.discrepancy.quantity_final = What is the final quantity ?\n' + +'cht-stock-monitoring-workflow.stock_supply.label.confirm_qty = Confirm quantities\ncht-stock-monitoring-workflow.stock_supply.message.set_unit_constraint_message = Should be in the form x/y for x {{set_label}} and y {{unit_label}}\ncht-stock-monitoring-workflow.stock_supply.message.unit_quantity_hint = Add the quantity: {{quantity}} {{unit_label}}'; + + const frMessage = 'cht-stock-monitoring-workflow.stock_supply.page_1.header = Sélectionner les élément à livrer\n'+ + 'cht-stock-monitoring-workflow.stock_supply.forms.select_category = Sélectionner les catégories des éléments à retourner\n'+ + 'cht-stock-monitoring-workflow.stock_supply.page_1.select_input = Sélectionner\n'+ + 'cht-stock-monitoring-workflow.stock_supply.page_1.select_input_hint = Sélectionner tous les éléments à livrer\n'+ + 'cht-stock-monitoring-workflow.stock_supply.item.stock_on_hand = Stock actuel\n'+ + 'cht-stock-monitoring-workflow.stock_supply.item.quantity_of = Quantité de\n'+ + 'cht-stock-monitoring-workflow.stock_supply.summary_header = Page Résultats\n'+ + 'cht-stock-monitoring-workflow.stock_supply.submit_note =

Assurez-vous de soumettre pour enregistrer cette action.

\n'+ + 'cht-stock-monitoring-workflow.stock_supply.summary_note = Stock livré.\n'+ + 'cht-stock-monitoring-workflow.stock_supply.tasks.reception-confirmation = Stock reçu\n'+ + 'cht-stock-monitoring-workflow.stock_supply.confirmation.item_received_confirmation_question = Avez-vous reçu {{qty_unit}}\n'+ + 'cht-stock-monitoring-workflow.stock_supply.choices.yes_no.yes = Oui\n'+ + 'cht-stock-monitoring-workflow.stock_supply.choices.yes_no.no = Non\n'+ + 'cht-stock-monitoring-workflow.stock_supply.forms.additional_doc_title = Stock utilsé\n'+ + 'cht-stock-monitoring-workflow.stock_supply.forms.item_used_question = Quantité de {{item}}\n'+ + 'cht-stock-monitoring-workflow.stock_supply.confirmation.qty_received_question = Entrer la quantité reçu\n'+ + 'cht-stock-monitoring-workflow.stock_supply.tasks.stock-descreptancy = Résolution Conflit\n'+ + 'cht-stock-monitoring-workflow.stock_supply.forms.select_items = Sélectionner les différents éléments que vous voulez livrer\n'+ + 'cht-stock-monitoring-workflow.stock_supply.confirmation.summary_note = Stock que vous avez reçu.\n'+ + 'cht-stock-monitoring-workflow.stock_supply.discrepancy.summary_header = Page Résultats\n'+ + 'cht-stock-monitoring-workflow.stock_supply.discrepancy.submit_note =

Assurez-vous de soumettre pour completer cette action.

\n'+ + 'cht-stock-monitoring-workflow.stock_supply.discrepancy.summary_note = Résolution de conflits\n'+ + 'cht-stock-monitoring-workflow.stock_supply.discrepancy.quantity_issued = Quantité envoyée: {{qty}}\n'+ + 'cht-stock-monitoring-workflow.stock_supply.discrepancy.quantity_confirmed = Quantité confirmée: {{qty}}\n'+ + 'cht-stock-monitoring-workflow.stock_supply.discrepancy.quantity_final = Quelle est la quantité finale ?\n'+ + 'cht-stock-monitoring-workflow.stock_supply.label.confirm_qty = Confirmer les quantités\n'+ + 'cht-stock-monitoring-workflow.stock_supply.message.set_unit_constraint_message = Should be in the form x/y for x {{set_label}} and y {{unit_label}}\n'+ + 'cht-stock-monitoring-workflow.stock_supply.message.unit_quantity_hint = Add the quantity: {{quantity}} {{unit_label}}'; + + beforeEach(async () => { + setDirToprojectConfig(); + await writeTranslationMessages(frMessage, enMessage, process.cwd()); + }); + + afterEach(async() => { + jest.clearAllMocks(); + await resetTranslationMessages(process.cwd()); + revertBackToProjectHome(workingDir); + process.argv = processInitialArgv; // Restore the original argv after each test + }); + + /** Testing getItemRows function */ + // Testing get item row function out config generation with no or wrong item config and params + it('This should throw error and should not generate rows with empty header, messages, languages(fr, en) and items to be added ', async () => { + + const header = []; + const messages = {}; + const items = [{}]; + + expect(() => getItemRows(header, stockMonitoringConfigs.languages, messages, items)).toThrow(TypeError); + + }); + + // Testing get item row function with correct item config and params + it('This should return rows with header, messages, languages(fr, en) and items to be added ', async () => { + + const header = [ + 'type', + 'name', + 'required', + 'relevant', + 'appearance', + 'constraint', + 'constraint_message', + 'calculation', + 'default', + 'label::en', + 'label::fr', + 'hint:en', + 'hint:fr' + ]; + + const messages = getTranslations(); + const items = Object.values(stockMonitoringConfigs.items); + + const row = getItemRows(header, stockMonitoringConfigs.languages, messages, items); + expect(row).not.toEqual([]); + expect(row.length).toBe(items.length); + const oneRow = row[0][0]; + expect(oneRow.length).toBe(13); + expect(oneRow[0]).toEqual('begin group'); + expect(oneRow[1]).toContain(items[0].name); + + }); + + /** Testing getSummaries function */ + it('This should return summaries based the item config provided ', async () => { + + const header = [ + 'type', + 'name', + 'required', + 'relevant', + 'appearance', + 'constraint', + 'constraint_message', + 'calculation', + 'default', + 'label::en', + 'label::fr', + 'hint:en', + 'hint:fr' + ]; + const items = Object.values(stockMonitoringConfigs.items); + const categories = Object.values(stockMonitoringConfigs.categories); + const languages = Object.values(stockMonitoringConfigs.languages); + const itemCategoryNoteSummury = [ + 'note', + 'malaria_summary', + '', + '${paracetamol_qty} > 0', + 'h1 blue', + '', + '', + '', + '', + '', + 'Categorie', + '', + '' + ]; + + const summaries = await getSummaries(languages, header, items, categories); + expect(summaries).toContainEqual(itemCategoryNoteSummury); + + }); + + // Testing get additional doc + it('This should return additional doc for stock discrepancy', async () => { + const header = [ + 'type', + 'name', + 'required', + 'relevant', + 'appearance', + 'constraint', + 'constraint_message', + 'calculation', + 'default', + 'label::en', + 'label::fr', + 'hint:en', + 'hint:fr' + ]; + + const items = Object.values(stockMonitoringConfigs.items); + const languages = Object.values(stockMonitoringConfigs.languages); + const form_name = stockMonitoringConfigs.features.stock_supply.discrepancy.form_name; + + const itemCalculation = [ + 'calculate', + 'paracetamol_out', + '', + '', + '', + '', + '', + "if(${paracetamol_qty} != '' and ${paracetamol___count} > 0,${paracetamol___count}-${paracetamol_confirmed},0)", + '', + '', + '', + '', + '' + ]; + + const additionalDoc = getAdditionalDoc(form_name, 'descrepancy_doc', languages, header, items); + expect(additionalDoc).toContainEqual(itemCalculation); + + }); + + /** Testing add export calculation to stock_order */ + it('should add export calculation correctly with items provided', async () => { + const items = Object.values(stockMonitoringConfigs.items); + const header = [ + 'type', + 'name', + 'required', + 'relevant', + 'appearance', + 'constraint', + 'constraint_message', + 'calculation', + 'default', + 'label::en', + 'label::fr', + 'hint:en', + 'hint:fr' + ]; + + const exprotCalculation =getExportCalculations(header, items); + + // Check that items are inserted in stock_return xform + const itemData = [ + [ + 'calculate', + 'paracetamol_in', + '', + '', + '', + '', + '', + "if(${paracetamol_qty} != '' and ${paracetamol___count} > 0,${paracetamol_received}-${paracetamol___count},0)", + '', + '', + '', + '', + '' + ] + ]; + + expect(exprotCalculation).toEqual(itemData); + + }); + + +}); diff --git a/test/stock-discrepancy-feature.spec.js b/test/stock-discrepancy-feature.spec.js index 4110d77..815b3a8 100644 --- a/test/stock-discrepancy-feature.spec.js +++ b/test/stock-discrepancy-feature.spec.js @@ -1,25 +1,71 @@ const fs = require('fs'); const path = require('path'); -const { stockSupplyConfig, mockConfigsWithNoFeauture } = require('./mocks/mocks'); +const ExcelJS = require('exceljs'); +const { stockMonitoringConfigs, mockConfigsWithNoFeauture } = require('./mocks/mocks'); const { updateStockDiscrepancy } = require('../src/features/stock-discrepancy'); const { setDirToprojectConfig, revertBackToProjectHome, - readOutputFiles, - cleanUp + cleanUp, + writeTranslationMessages, + resetTranslationMessages } = require('./test-utils'); describe('update Stock Discrepancy', () => { const workingDir = process.cwd(); const createdAppFormFiles = ['stock_discrepancy_resolution.xlsx', 'stock_discrepancy_resolution.properties.json']; - beforeEach(() => { + const enMessage = 'cht-stock-monitoring-workflow.stock_supply.page_1.header = Select item to supply\ncht-stock-monitoring-workflow.stock_supply.forms.select_category = Select the category of what you want to return\n' + +'cht-stock-monitoring-workflow.stock_supply.page_1.select_input = Select\ncht-stock-monitoring-workflow.stock_supply.page_1.select_input_hint = Select all items to supply\ncht-stock-monitoring-workflow.stock_supply.item.stock_on_hand = Stock on hand\ncht-stock-monitoring-workflow.stock_supply.item.quantity_of = Quantity of\n' + +'cht-stock-monitoring-workflow.stock_supply.summary_header = Results/Summary page\ncht-stock-monitoring-workflow.stock_supply.submit_note =

Be sure you Submit to complete this action.

\n' + +'cht-stock-monitoring-workflow.stock_supply.summary_note = Stock items you supply.\ncht-stock-monitoring-workflow.stock_supply.tasks.reception-confirmation = Stock received\n' + +'cht-stock-monitoring-workflow.stock_supply.confirmation.item_received_confirmation_question = Did you received {{qty_unit}}\ncht-stock-monitoring-workflow.stock_supply.choices.yes_no.yes = Yes\n' + +'cht-stock-monitoring-workflow.stock_supply.choices.yes_no.no = No\ncht-stock-monitoring-workflow.stock_supply.forms.additional_doc_title = Stock uses\ncht-stock-monitoring-workflow.stock_supply.forms.item_used_question = Quantity of {{item}}\n' + +'cht-stock-monitoring-workflow.stock_supply.confirmation.qty_received_question = Enter the quantity received\ncht-stock-monitoring-workflow.stock_supply.tasks.stock-descreptancy = Commodity Discrepancy Resolution\n' + +'cht-stock-monitoring-workflow.stock_supply.forms.select_items = Select the different item you want to supply\ncht-stock-monitoring-workflow.stock_supply.confirmation.summary_note = Stock items you received.\n' + +'cht-stock-monitoring-workflow.stock_supply.discrepancy.summary_header = Results/Summary page\ncht-stock-monitoring-workflow.stock_supply.discrepancy.submit_note =

Be sure you Submit to complete this action.

\n' + +'cht-stock-monitoring-workflow.stock_supply.discrepancy.summary_note = Discrepancy resolution\ncht-stock-monitoring-workflow.stock_supply.discrepancy.quantity_issued = Quantity issued: {{qty}}\n' + +'cht-stock-monitoring-workflow.stock_supply.discrepancy.quantity_confirmed = Quantity confirmed: {{qty}}\ncht-stock-monitoring-workflow.stock_supply.discrepancy.quantity_final = What is the final quantity ?\n' + +'cht-stock-monitoring-workflow.stock_supply.label.confirm_qty = Confirm quantities\ncht-stock-monitoring-workflow.stock_supply.message.set_unit_constraint_message = Should be in the form x/y for x {{set_label}} and y {{unit_label}}\ncht-stock-monitoring-workflow.stock_supply.message.unit_quantity_hint = Add the quantity: {{quantity}} {{unit_label}}'; + + const frMessage = 'cht-stock-monitoring-workflow.stock_supply.page_1.header = Sélectionner les élément à livrer\n'+ + 'cht-stock-monitoring-workflow.stock_supply.forms.select_category = Sélectionner les catégories des éléments à retourner\n'+ + 'cht-stock-monitoring-workflow.stock_supply.page_1.select_input = Sélectionner\n'+ + 'cht-stock-monitoring-workflow.stock_supply.page_1.select_input_hint = Sélectionner tous les éléments à livrer\n'+ + 'cht-stock-monitoring-workflow.stock_supply.item.stock_on_hand = Stock actuel\n'+ + 'cht-stock-monitoring-workflow.stock_supply.item.quantity_of = Quantité de\n'+ + 'cht-stock-monitoring-workflow.stock_supply.summary_header = Page Résultats\n'+ + 'cht-stock-monitoring-workflow.stock_supply.submit_note =

Assurez-vous de soumettre pour enregistrer cette action.

\n'+ + 'cht-stock-monitoring-workflow.stock_supply.summary_note = Stock livré.\n'+ + 'cht-stock-monitoring-workflow.stock_supply.tasks.reception-confirmation = Stock reçu\n'+ + 'cht-stock-monitoring-workflow.stock_supply.confirmation.item_received_confirmation_question = Avez-vous reçu {{qty_unit}}\n'+ + 'cht-stock-monitoring-workflow.stock_supply.choices.yes_no.yes = Oui\n'+ + 'cht-stock-monitoring-workflow.stock_supply.choices.yes_no.no = Non\n'+ + 'cht-stock-monitoring-workflow.stock_supply.forms.additional_doc_title = Stock utilsé\n'+ + 'cht-stock-monitoring-workflow.stock_supply.forms.item_used_question = Quantité de {{item}}\n'+ + 'cht-stock-monitoring-workflow.stock_supply.confirmation.qty_received_question = Entrer la quantité reçu\n'+ + 'cht-stock-monitoring-workflow.stock_supply.tasks.stock-descreptancy = Résolution Conflit\n'+ + 'cht-stock-monitoring-workflow.stock_supply.forms.select_items = Sélectionner les différents éléments que vous voulez livrer\n'+ + 'cht-stock-monitoring-workflow.stock_supply.confirmation.summary_note = Stock que vous avez reçu.\n'+ + 'cht-stock-monitoring-workflow.stock_supply.discrepancy.summary_header = Page Résultats\n'+ + 'cht-stock-monitoring-workflow.stock_supply.discrepancy.submit_note =

Assurez-vous de soumettre pour completer cette action.

\n'+ + 'cht-stock-monitoring-workflow.stock_supply.discrepancy.summary_note = Résolution de conflits\n'+ + 'cht-stock-monitoring-workflow.stock_supply.discrepancy.quantity_issued = Quantité envoyée: {{qty}}\n'+ + 'cht-stock-monitoring-workflow.stock_supply.discrepancy.quantity_confirmed = Quantité confirmée: {{qty}}\n'+ + 'cht-stock-monitoring-workflow.stock_supply.discrepancy.quantity_final = Quelle est la quantité finale ?\n'+ + 'cht-stock-monitoring-workflow.stock_supply.label.confirm_qty = Confirmer les quantités\n'+ + 'cht-stock-monitoring-workflow.stock_supply.message.set_unit_constraint_message = Should be in the form x/y for x {{set_label}} and y {{unit_label}}\n'+ + 'cht-stock-monitoring-workflow.stock_supply.message.unit_quantity_hint = Add the quantity: {{quantity}} {{unit_label}}'; + + beforeEach(async() => { setDirToprojectConfig(); + await writeTranslationMessages(frMessage, enMessage, process.cwd()); }); afterEach(async() => { // Remove the generated files await cleanUp(workingDir, createdAppFormFiles); + await resetTranslationMessages(process.cwd()); revertBackToProjectHome(workingDir); jest.clearAllMocks(); }); @@ -45,14 +91,16 @@ describe('update Stock Discrepancy', () => { expect(fs.existsSync(path.join(processDir, 'forms', 'app', createdAppFormFile))).toBe(false); } // Call the function updateStockDiscrepancy and check that the stock_received files are generated - await updateStockDiscrepancy(stockSupplyConfig); + await updateStockDiscrepancy(stockMonitoringConfigs); for(const createdAppFormFile of createdAppFormFiles){ expect(fs.existsSync(path.join(processDir, 'forms', 'app', createdAppFormFile))).toBe(true); } // Check that stock received files content are correctly written. - const {workbook, propertiesFileContent} = await readOutputFiles(createdAppFormFiles); + const formPath = path.join(processDir, 'forms', 'app', 'stock_discrepancy_resolution.xlsx'); + const workbook = new ExcelJS.Workbook(); + await workbook.xlsx.readFile(formPath); const spy = jest.spyOn(workbook, 'getWorksheet'); const surveyWorkSheet = workbook.getWorksheet('survey'); expect(spy).toHaveBeenCalledTimes(1); @@ -63,6 +111,11 @@ describe('update Stock Discrepancy', () => { expect(surveyWorkSheet).not.toEqual([]); expect(settingWorkSheet).not.toEqual([]); + const propertiesFileContent = fs.readFileSync( + path.join(processDir, 'forms', 'app', 'stock_discrepancy_resolution.properties.json'), + {encoding: 'utf-8'} + ); + expect(JSON.parse(propertiesFileContent)).toEqual({ 'context': { 'expression': 'user.parent.contact_type === \'c50_supervision_area\' && user.role === \'supervisor\'', diff --git a/test/stock-out-feature-functions.spec.js b/test/stock-out-feature-functions.spec.js index b5810b0..62a281d 100644 --- a/test/stock-out-feature-functions.spec.js +++ b/test/stock-out-feature-functions.spec.js @@ -1,5 +1,5 @@ const { - stockOutMockConfigs, + stockMonitoringConfigs, mockConfigsWithNoFeauture } = require('./mocks/mocks'); @@ -43,7 +43,7 @@ describe('Testing functions in Stock out feature file', () => { const messages = {}; const items = [{}]; - expect(() => getItemRows(header, stockOutMockConfigs.languages, messages, items)).toThrow(TypeError); + expect(() => getItemRows(header, stockMonitoringConfigs.languages, messages, items)).toThrow(TypeError); }); @@ -67,9 +67,9 @@ describe('Testing functions in Stock out feature file', () => { ]; const messages = getTranslations(); - const items = Object.values(stockOutMockConfigs.items); + const items = Object.values(stockMonitoringConfigs.items); - const row = getItemRows(header, stockOutMockConfigs.languages, messages, items); + const row = getItemRows(header, stockMonitoringConfigs.languages, messages, items); expect(row).not.toEqual([]); expect(row.length).toBe(items.length); expect(row[0].length).toBe(7); @@ -89,7 +89,7 @@ describe('Testing functions in Stock out feature file', () => { formular: 'item_danger_qty', title: { en: 'Stock Out', fr: ' Rupture de Stock' } }; - const featureConfigs = await getStockOutConfigs(stockOutMockConfigs); + const featureConfigs = await getStockOutConfigs(stockMonitoringConfigs); expect(featureConfigs).toEqual(configs); }); diff --git a/test/stock-out-feature.spec.js b/test/stock-out-feature.spec.js index 3617e12..aadeed7 100644 --- a/test/stock-out-feature.spec.js +++ b/test/stock-out-feature.spec.js @@ -1,7 +1,7 @@ const ExcelJS = require('exceljs'); const fs = require('fs'); const path = require('path'); -const { stockOutMockConfigs, mockConfigsWithNoFeauture } = require('./mocks/mocks'); +const { stockMonitoringConfigs, mockConfigsWithNoFeauture } = require('./mocks/mocks'); const { updateStockOut } = require('../src/features/stock-out'); const { setDirToprojectConfig, @@ -47,7 +47,7 @@ describe('Create and update stock_out.xlsx and properties files ', () => { expect(fs.existsSync(path.join(processDir, 'forms', 'app', createdAppFormFile))).toBe(false); } // Call the function updateStockOut and check that the stock_out files are generated - await updateStockOut(stockOutMockConfigs); + await updateStockOut(stockMonitoringConfigs); for(const createdAppFormFile of createdAppFormFiles){ expect(fs.existsSync(path.join(processDir, 'forms', 'app', createdAppFormFile))).toBe(true); diff --git a/test/stock-out-integration.spec.js b/test/stock-out-integration.spec.js index bcbc755..c50c49d 100644 --- a/test/stock-out-integration.spec.js +++ b/test/stock-out-integration.spec.js @@ -2,7 +2,7 @@ const { spawnSync } = require('child_process'); const path = require('path'); const fs = require('fs-extra'); -const { stockOutScenario, stockCountScenario } = require('./mocks/mocks'); +const { stockMonitoringScenario, stockOutScenario, stockCountScenario } = require('./mocks/mocks'); const { setDirToprojectConfig, revertBackToProjectHome, @@ -31,7 +31,7 @@ describe('Create and update stock_out.xlsx and properties files', () => { afterEach(async() => { await resetTranslationMessages(process.cwd()); - cleanUp(workingDir, createdAppFormFiles); + await cleanUp(workingDir, createdAppFormFiles); revertBackToProjectHome(workingDir); }); @@ -43,7 +43,7 @@ describe('Create and update stock_out.xlsx and properties files', () => { expect(fs.existsSync(path.join(processDir, 'forms', 'app', createdAppFormFile))).toBe(false); } - const childProcess = spawnSync('../../main.js', stockOutScenario.initScenario); + const childProcess = spawnSync('../../main.js', stockMonitoringScenario.initScenario); if (childProcess.error) { throw childProcess.error; diff --git a/test/stock-received-feature-functions.spec.js b/test/stock-received-feature-functions.spec.js new file mode 100644 index 0000000..6e0c7ff --- /dev/null +++ b/test/stock-received-feature-functions.spec.js @@ -0,0 +1,234 @@ +const path = require('path'); +const ExcelJS = require('exceljs'); +const { + stockMonitoringConfigs +} = require('./mocks/mocks'); + +const { + getItemRows, + updateStockConfirmation, + addStockConfirmCalculation, + addStockConfirmSummaries, + getLabelColumns +} = require('../src/features/stock-received'); + +const { + setDirToprojectConfig, + revertBackToProjectHome, + writeTranslationMessages, + resetTranslationMessages, + cleanUp, + readDataFromXforms +} = require('./test-utils'); + +const { getTranslations } = require('../src/common'); + +describe('Testing functions in Stock out feature file', () => { + const workingDir = process.cwd(); + const createdAppFiles = ['stock_received.xlsx', 'stock_received.properties.json']; + const enMessage = 'cht-stock-monitoring-workflow.stock_supply.page_1.header = Select item to supply\ncht-stock-monitoring-workflow.stock_supply.forms.select_category = Select the category of what you want to return\n' + +'cht-stock-monitoring-workflow.stock_supply.page_1.select_input = Select\ncht-stock-monitoring-workflow.stock_supply.page_1.select_input_hint = Select all items to supply\ncht-stock-monitoring-workflow.stock_supply.item.stock_on_hand = Stock on hand\ncht-stock-monitoring-workflow.stock_supply.item.quantity_of = Quantity of\n' + +'cht-stock-monitoring-workflow.stock_supply.summary_header = Results/Summary page\ncht-stock-monitoring-workflow.stock_supply.submit_note =

Be sure you Submit to complete this action.

\n' + +'cht-stock-monitoring-workflow.stock_supply.summary_note = Stock items you supply.\ncht-stock-monitoring-workflow.stock_supply.tasks.reception-confirmation = Stock received\n' + +'cht-stock-monitoring-workflow.stock_supply.confirmation.item_received_confirmation_question = Did you received {{qty_unit}}\ncht-stock-monitoring-workflow.stock_supply.choices.yes_no.yes = Yes\n' + +'cht-stock-monitoring-workflow.stock_supply.choices.yes_no.no = No\ncht-stock-monitoring-workflow.stock_supply.forms.additional_doc_title = Stock uses\ncht-stock-monitoring-workflow.stock_supply.forms.item_used_question = Quantity of {{item}}\n' + +'cht-stock-monitoring-workflow.stock_supply.confirmation.qty_received_question = Enter the quantity received\ncht-stock-monitoring-workflow.stock_supply.tasks.stock-descreptancy = Commodity Discrepancy Resolution\n' + +'cht-stock-monitoring-workflow.stock_supply.forms.select_items = Select the different item you want to supply\ncht-stock-monitoring-workflow.stock_supply.confirmation.summary_note = Stock items you received.\n' + +'cht-stock-monitoring-workflow.stock_supply.discrepancy.summary_header = Results/Summary page\ncht-stock-monitoring-workflow.stock_supply.discrepancy.submit_note =

Be sure you Submit to complete this action.

\n' + +'cht-stock-monitoring-workflow.stock_supply.discrepancy.summary_note = Discrepancy resolution\ncht-stock-monitoring-workflow.stock_supply.discrepancy.quantity_issued = Quantity issued: {{qty}}\n' + +'cht-stock-monitoring-workflow.stock_supply.discrepancy.quantity_confirmed = Quantity confirmed: {{qty}}\ncht-stock-monitoring-workflow.stock_supply.discrepancy.quantity_final = What is the final quantity ?\n' + +'cht-stock-monitoring-workflow.stock_supply.label.confirm_qty = Confirm quantities\ncht-stock-monitoring-workflow.stock_supply.message.set_unit_constraint_message = Should be in the form x/y for x {{set_label}} and y {{unit_label}}\ncht-stock-monitoring-workflow.stock_supply.message.unit_quantity_hint = Add the quantity: {{quantity}} {{unit_label}}'; + + const frMessage = 'cht-stock-monitoring-workflow.stock_supply.page_1.header = Sélectionner les élément à livrer\n'+ + 'cht-stock-monitoring-workflow.stock_supply.forms.select_category = Sélectionner les catégories des éléments à retourner\n'+ + 'cht-stock-monitoring-workflow.stock_supply.page_1.select_input = Sélectionner\n'+ + 'cht-stock-monitoring-workflow.stock_supply.page_1.select_input_hint = Sélectionner tous les éléments à livrer\n'+ + 'cht-stock-monitoring-workflow.stock_supply.item.stock_on_hand = Stock actuel\n'+ + 'cht-stock-monitoring-workflow.stock_supply.item.quantity_of = Quantité de\n'+ + 'cht-stock-monitoring-workflow.stock_supply.summary_header = Page Résultats\n'+ + 'cht-stock-monitoring-workflow.stock_supply.submit_note =

Assurez-vous de soumettre pour enregistrer cette action.

\n'+ + 'cht-stock-monitoring-workflow.stock_supply.summary_note = Stock livré.\n'+ + 'cht-stock-monitoring-workflow.stock_supply.tasks.reception-confirmation = Stock reçu\n'+ + 'cht-stock-monitoring-workflow.stock_supply.confirmation.item_received_confirmation_question = Avez-vous reçu {{qty_unit}}\n'+ + 'cht-stock-monitoring-workflow.stock_supply.choices.yes_no.yes = Oui\n'+ + 'cht-stock-monitoring-workflow.stock_supply.choices.yes_no.no = Non\n'+ + 'cht-stock-monitoring-workflow.stock_supply.forms.additional_doc_title = Stock utilsé\n'+ + 'cht-stock-monitoring-workflow.stock_supply.forms.item_used_question = Quantité de {{item}}\n'+ + 'cht-stock-monitoring-workflow.stock_supply.confirmation.qty_received_question = Entrer la quantité reçu\n'+ + 'cht-stock-monitoring-workflow.stock_supply.tasks.stock-descreptancy = Résolution Conflit\n'+ + 'cht-stock-monitoring-workflow.stock_supply.forms.select_items = Sélectionner les différents éléments que vous voulez livrer\n'+ + 'cht-stock-monitoring-workflow.stock_supply.confirmation.summary_note = Stock que vous avez reçu.\n'+ + 'cht-stock-monitoring-workflow.stock_supply.discrepancy.summary_header = Page Résultats\n'+ + 'cht-stock-monitoring-workflow.stock_supply.discrepancy.submit_note =

Assurez-vous de soumettre pour completer cette action.

\n'+ + 'cht-stock-monitoring-workflow.stock_supply.discrepancy.summary_note = Résolution de conflits\n'+ + 'cht-stock-monitoring-workflow.stock_supply.discrepancy.quantity_issued = Quantité envoyée: {{qty}}\n'+ + 'cht-stock-monitoring-workflow.stock_supply.discrepancy.quantity_confirmed = Quantité confirmée: {{qty}}\n'+ + 'cht-stock-monitoring-workflow.stock_supply.discrepancy.quantity_final = Quelle est la quantité finale ?\n'+ + 'cht-stock-monitoring-workflow.stock_supply.label.confirm_qty = Confirmer les quantités\n'+ + 'cht-stock-monitoring-workflow.stock_supply.message.set_unit_constraint_message = Should be in the form x/y for x {{set_label}} and y {{unit_label}}\n'+ + 'cht-stock-monitoring-workflow.stock_supply.message.unit_quantity_hint = Add the quantity: {{quantity}} {{unit_label}}'; + + beforeEach(async () => { + setDirToprojectConfig(); + await writeTranslationMessages(frMessage, enMessage, process.cwd()); + }); + + afterEach(async() => { + jest.clearAllMocks(); + await resetTranslationMessages(process.cwd()); + await cleanUp(workingDir, createdAppFiles); + revertBackToProjectHome(workingDir); + }); + + /** Testing getItemRows function */ + // Testing get item row function with no header + it('This should throw error and should not generate rows with empty header, messages, languages(fr, en) and items to be added ', async () => { + + const header = []; + const messages = {}; + const items = [{}]; + + expect(() => getItemRows(header, stockMonitoringConfigs.languages, messages, items)).toThrow(TypeError); + + }); + + // Testing get item row function + it('This should return rows with header, messages, languages(fr, en) and items to be added ', async () => { + + const header = [ + 'type', + 'name', + 'required', + 'relevant', + 'appearance', + 'constraint', + 'constraint_message', + 'calculation', + 'default', + 'label::en', + 'label::fr', + 'hint:en', + 'hint:fr' + ]; + + const messages = getTranslations(); + const items = Object.values(stockMonitoringConfigs.items); + + const row = getItemRows(header, stockMonitoringConfigs.languages, messages, items); + expect(row).not.toEqual([]); + expect(row.length).toBe(items.length); + const oneRow = row[0][0]; + expect(oneRow.length).toBe(13); + expect(oneRow[0]).toEqual('begin group'); + expect(oneRow[1]).toContain(items[0].name); + + }); + + /** Testing add confirmation calculation to stock_received */ + it('should add confirmation calculation correctly with items provided', async () => { + const items = Object.values(stockMonitoringConfigs.items); + const projectDataDir = process.cwd(); + const messages = getTranslations(); + + // Call the function updateStockOrder and check that the stock_order files are generated + await updateStockConfirmation(stockMonitoringConfigs, messages); + + const formPath = path.join(projectDataDir, 'forms', 'app', 'stock_received.xlsx'); + const workbook = new ExcelJS.Workbook(); + await workbook.xlsx.readFile(formPath); + const surveyWorkSheet = workbook.getWorksheet('survey'); + + addStockConfirmCalculation(surveyWorkSheet, items); + + // Check that items are inserted in stock_return xform + const itemData = []; + for (const item of items){ + itemData.push(`${item.name}_confirmed`); + } + const stockOrderData = await readDataFromXforms(['out'], itemData, 'stock_received.xlsx' ); + + expect(stockOrderData.productsList.length).toBe(itemData.length); + for(let index =0; index < itemData.length; index ++){ + expect(stockOrderData.productsList[index]).toEqual(itemData[index]); + } + + }); + + /** Testing add summaries to stock_received */ + it('should add summaries correctly when categories and items are provided', async () => { + const languages = Object.values(stockMonitoringConfigs.languages); + const items = Object.values(stockMonitoringConfigs.items); + const categories = Object.values(stockMonitoringConfigs.categories); + const projectDataDir = process.cwd(); + const messages = getTranslations(); + + // Call the function updateStockConfirmation and check that the stock_received files are generated + await updateStockConfirmation(stockMonitoringConfigs, messages); + + const formPath = path.join(projectDataDir, 'forms', 'app', 'stock_received.xlsx'); + const workbook = new ExcelJS.Workbook(); + await workbook.xlsx.readFile(formPath); + const surveyWorkSheet = workbook.getWorksheet('survey'); + + addStockConfirmSummaries(surveyWorkSheet, languages, items, categories); + + // Check that items are inserted in stock_returned xform + const categoryNames = categories.map((category) => `${category.name}_summary`); + const itemNames =[]; + for(const item of items){ + itemNames.push(`${item.name}_summary_yes`); + itemNames.push(`${item.name}_summary_no`); + } + const stockOrderData = await readDataFromXforms(categoryNames, itemNames,'stock_received.xlsx' ); + + expect(stockOrderData.productsList.length).toBe(itemNames.length); + expect(stockOrderData.productsList.entries).toStrictEqual(itemNames.entries); + expect(stockOrderData.productCategoryList.length).toBe(categoryNames.length); + expect(stockOrderData.productCategoryList.entries).toStrictEqual(categoryNames.entries); + + }); + + /** Testing get labels for to stock_received */ + it('should get label for messages and language provided', async () => { + const languages = Object.values(stockMonitoringConfigs.languages); + const messages = getTranslations(true); + const labels = + [ + 'label::en', + 'Patient', + 'Source', + 'Source ID', + 'NO_LABEL', + 'NO_LABEL', + '', + 'NO_LABEL', + 'NO_LABEL', + 'NO_LABEL', + '', + '', + '', + '', + '', + '', + 'Results/Summary page', + '

Be sure you Submit to complete this action.

', + 'Stock items you received.', + '', + '', + 'NO_LABEL' + ]; + + // Call the function getLabelColumns + const outputLabels = getLabelColumns(languages, messages); + + // Check that the label are generated based on messages contain + const subArrayOutput = outputLabels[0]; + const containsSubArray = subArrayOutput.some(subArray => { + return JSON.stringify(subArray) === JSON.stringify(labels); + }); + expect(containsSubArray).toBe(true); + expect(subArrayOutput).toContainEqual(labels); + + }); + +}); diff --git a/test/stock-received-feature.spec.js b/test/stock-received-feature.spec.js index 27421b3..056e6ad 100644 --- a/test/stock-received-feature.spec.js +++ b/test/stock-received-feature.spec.js @@ -1,26 +1,72 @@ const fs = require('fs'); const path = require('path'); -const { stockSupplyConfig, mockConfigsWithNoFeauture } = require('./mocks/mocks'); +const ExcelJS = require('exceljs'); +const { stockMonitoringConfigs, mockConfigsWithNoFeauture } = require('./mocks/mocks'); const { updateStockConfirmation } = require('../src/features/stock-received'); const { getTranslations } = require('../src/common'); const { setDirToprojectConfig, revertBackToProjectHome, - readOutputFiles, + writeTranslationMessages, + resetTranslationMessages, cleanUp } = require('./test-utils'); describe('update Stock Received', () => { const workingDir = process.cwd(); const createdAppFormFiles = ['stock_received.xlsx', 'stock_received.properties.json']; + const enMessage = 'cht-stock-monitoring-workflow.stock_supply.page_1.header = Select item to supply\ncht-stock-monitoring-workflow.stock_supply.forms.select_category = Select the category of what you want to return\n' + +'cht-stock-monitoring-workflow.stock_supply.page_1.select_input = Select\ncht-stock-monitoring-workflow.stock_supply.page_1.select_input_hint = Select all items to supply\ncht-stock-monitoring-workflow.stock_supply.item.stock_on_hand = Stock on hand\ncht-stock-monitoring-workflow.stock_supply.item.quantity_of = Quantity of\n' + +'cht-stock-monitoring-workflow.stock_supply.summary_header = Results/Summary page\ncht-stock-monitoring-workflow.stock_supply.submit_note =

Be sure you Submit to complete this action.

\n' + +'cht-stock-monitoring-workflow.stock_supply.summary_note = Stock items you supply.\ncht-stock-monitoring-workflow.stock_supply.tasks.reception-confirmation = Stock received\n' + +'cht-stock-monitoring-workflow.stock_supply.confirmation.item_received_confirmation_question = Did you received {{qty_unit}}\ncht-stock-monitoring-workflow.stock_supply.choices.yes_no.yes = Yes\n' + +'cht-stock-monitoring-workflow.stock_supply.choices.yes_no.no = No\ncht-stock-monitoring-workflow.stock_supply.forms.additional_doc_title = Stock uses\ncht-stock-monitoring-workflow.stock_supply.forms.item_used_question = Quantity of {{item}}\n' + +'cht-stock-monitoring-workflow.stock_supply.confirmation.qty_received_question = Enter the quantity received\ncht-stock-monitoring-workflow.stock_supply.tasks.stock-descreptancy = Commodity Discrepancy Resolution\n' + +'cht-stock-monitoring-workflow.stock_supply.forms.select_items = Select the different item you want to supply\ncht-stock-monitoring-workflow.stock_supply.confirmation.summary_note = Stock items you received.\n' + +'cht-stock-monitoring-workflow.stock_supply.discrepancy.summary_header = Results/Summary page\ncht-stock-monitoring-workflow.stock_supply.discrepancy.submit_note =

Be sure you Submit to complete this action.

\n' + +'cht-stock-monitoring-workflow.stock_supply.discrepancy.summary_note = Discrepancy resolution\ncht-stock-monitoring-workflow.stock_supply.discrepancy.quantity_issued = Quantity issued: {{qty}}\n' + +'cht-stock-monitoring-workflow.stock_supply.discrepancy.quantity_confirmed = Quantity confirmed: {{qty}}\ncht-stock-monitoring-workflow.stock_supply.discrepancy.quantity_final = What is the final quantity ?\n' + +'cht-stock-monitoring-workflow.stock_supply.label.confirm_qty = Confirm quantities\ncht-stock-monitoring-workflow.stock_supply.message.set_unit_constraint_message = Should be in the form x/y for x {{set_label}} and y {{unit_label}}\ncht-stock-monitoring-workflow.stock_supply.message.unit_quantity_hint = Add the quantity: {{quantity}} {{unit_label}}'; + + const frMessage = 'cht-stock-monitoring-workflow.stock_supply.page_1.header = Sélectionner les élément à livrer\n'+ + 'cht-stock-monitoring-workflow.stock_supply.forms.select_category = Sélectionner les catégories des éléments à retourner\n'+ + 'cht-stock-monitoring-workflow.stock_supply.page_1.select_input = Sélectionner\n'+ + 'cht-stock-monitoring-workflow.stock_supply.page_1.select_input_hint = Sélectionner tous les éléments à livrer\n'+ + 'cht-stock-monitoring-workflow.stock_supply.item.stock_on_hand = Stock actuel\n'+ + 'cht-stock-monitoring-workflow.stock_supply.item.quantity_of = Quantité de\n'+ + 'cht-stock-monitoring-workflow.stock_supply.summary_header = Page Résultats\n'+ + 'cht-stock-monitoring-workflow.stock_supply.submit_note =

Assurez-vous de soumettre pour enregistrer cette action.

\n'+ + 'cht-stock-monitoring-workflow.stock_supply.summary_note = Stock livré.\n'+ + 'cht-stock-monitoring-workflow.stock_supply.tasks.reception-confirmation = Stock reçu\n'+ + 'cht-stock-monitoring-workflow.stock_supply.confirmation.item_received_confirmation_question = Avez-vous reçu {{qty_unit}}\n'+ + 'cht-stock-monitoring-workflow.stock_supply.choices.yes_no.yes = Oui\n'+ + 'cht-stock-monitoring-workflow.stock_supply.choices.yes_no.no = Non\n'+ + 'cht-stock-monitoring-workflow.stock_supply.forms.additional_doc_title = Stock utilsé\n'+ + 'cht-stock-monitoring-workflow.stock_supply.forms.item_used_question = Quantité de {{item}}\n'+ + 'cht-stock-monitoring-workflow.stock_supply.confirmation.qty_received_question = Entrer la quantité reçu\n'+ + 'cht-stock-monitoring-workflow.stock_supply.tasks.stock-descreptancy = Résolution Conflit\n'+ + 'cht-stock-monitoring-workflow.stock_supply.forms.select_items = Sélectionner les différents éléments que vous voulez livrer\n'+ + 'cht-stock-monitoring-workflow.stock_supply.confirmation.summary_note = Stock que vous avez reçu.\n'+ + 'cht-stock-monitoring-workflow.stock_supply.discrepancy.summary_header = Page Résultats\n'+ + 'cht-stock-monitoring-workflow.stock_supply.discrepancy.submit_note =

Assurez-vous de soumettre pour completer cette action.

\n'+ + 'cht-stock-monitoring-workflow.stock_supply.discrepancy.summary_note = Résolution de conflits\n'+ + 'cht-stock-monitoring-workflow.stock_supply.discrepancy.quantity_issued = Quantité envoyée: {{qty}}\n'+ + 'cht-stock-monitoring-workflow.stock_supply.discrepancy.quantity_confirmed = Quantité confirmée: {{qty}}\n'+ + 'cht-stock-monitoring-workflow.stock_supply.discrepancy.quantity_final = Quelle est la quantité finale ?\n'+ + 'cht-stock-monitoring-workflow.stock_supply.label.confirm_qty = Confirmer les quantités\n'+ + 'cht-stock-monitoring-workflow.stock_supply.message.set_unit_constraint_message = Should be in the form x/y for x {{set_label}} and y {{unit_label}}\n'+ + 'cht-stock-monitoring-workflow.stock_supply.message.unit_quantity_hint = Add the quantity: {{quantity}} {{unit_label}}'; - beforeEach(() => { + + beforeEach(async () => { setDirToprojectConfig(); + await writeTranslationMessages(frMessage, enMessage, process.cwd()); }); afterEach(async () => { // Remove the generated files await cleanUp(workingDir, createdAppFormFiles); + await resetTranslationMessages(process.cwd()); revertBackToProjectHome(workingDir); jest.clearAllMocks(); }); @@ -48,14 +94,16 @@ describe('update Stock Received', () => { // Call the function updateStockConfirmation and check that the stock_received files are generated const messages = getTranslations(); expect(messages.length).not.toEqual(0); - await updateStockConfirmation(stockSupplyConfig, messages); + await updateStockConfirmation(stockMonitoringConfigs, messages); for(const createdAppFormFile of createdAppFormFiles){ expect(fs.existsSync(path.join(processDir, 'forms', 'app', createdAppFormFile))).toBe(true); } // Check that stock received files content are correctly written. - const {workbook, propertiesFileContent} = await readOutputFiles(createdAppFormFiles); + const formPath = path.join(processDir, 'forms', 'app', 'stock_received.xlsx'); + const workbook = new ExcelJS.Workbook(); + await workbook.xlsx.readFile(formPath); const spy = jest.spyOn(workbook, 'getWorksheet'); const surveyWorkSheet = workbook.getWorksheet('survey'); expect(spy).toHaveBeenCalledTimes(1); @@ -66,6 +114,11 @@ describe('update Stock Received', () => { expect(surveyWorkSheet).not.toEqual([]); expect(settingWorkSheet).not.toEqual([]); + const propertiesFileContent = fs.readFileSync( + path.join(processDir, 'forms', 'app', 'stock_received.properties.json'), + {encoding: 'utf-8'} + ); + expect(JSON.parse(propertiesFileContent)).toEqual({ 'context': { 'expression': 'user.parent.contact_type === \'c62_chw_site\'', diff --git a/test/stock-supply-feature-functions.spec.js b/test/stock-supply-feature-functions.spec.js new file mode 100644 index 0000000..66e6b82 --- /dev/null +++ b/test/stock-supply-feature-functions.spec.js @@ -0,0 +1,270 @@ +const path = require('path'); +const ExcelJS = require('exceljs'); +const { + stockMonitoringConfigs, + mockConfigsWithNoFeauture +} = require('./mocks/mocks'); + +const { + getItemRows, + updateStockSupply, + getStockSupplyConfigs, + addStockSupplyCalculation, + getAdditionalDoc, + addStockSupplySummaries, + +} = require('../src/features/stock-supply'); + +const { + setDirToprojectConfig, + revertBackToProjectHome, + writeTranslationMessages, + resetTranslationMessages, + readDataFromXforms, + cleanUp +} = require('./test-utils'); + +const { getTranslations } = require('../src/common'); + +describe('Testing functions in Stock out feature file', () => { + const processInitialArgv = process.argv; // Save the original argv + const workingDir = process.cwd(); + const createdAppFiles = ['stock_received.xlsx', 'stock_received.properties.json', 'stock_supply.xlsx', 'stock_supply.properties.json']; + const enMessage = 'cht-stock-monitoring-workflow.stock_supply.page_1.header = Select item to supply\ncht-stock-monitoring-workflow.stock_supply.forms.select_category = Select the category of what you want to return\n' + +'cht-stock-monitoring-workflow.stock_supply.page_1.select_input = Select\ncht-stock-monitoring-workflow.stock_supply.page_1.select_input_hint = Select all items to supply\ncht-stock-monitoring-workflow.stock_supply.item.stock_on_hand = Stock on hand\ncht-stock-monitoring-workflow.stock_supply.item.quantity_of = Quantity of\n' + +'cht-stock-monitoring-workflow.stock_supply.summary_header = Results/Summary page\ncht-stock-monitoring-workflow.stock_supply.submit_note =

Be sure you Submit to complete this action.

\n' + +'cht-stock-monitoring-workflow.stock_supply.summary_note = Stock items you supply.\ncht-stock-monitoring-workflow.stock_supply.tasks.reception-confirmation = Stock received\n' + +'cht-stock-monitoring-workflow.stock_supply.confirmation.item_received_confirmation_question = Did you received {{qty_unit}}\ncht-stock-monitoring-workflow.stock_supply.choices.yes_no.yes = Yes\n' + +'cht-stock-monitoring-workflow.stock_supply.choices.yes_no.no = No\ncht-stock-monitoring-workflow.stock_supply.forms.additional_doc_title = Stock uses\ncht-stock-monitoring-workflow.stock_supply.forms.item_used_question = Quantity of {{item}}\n' + +'cht-stock-monitoring-workflow.stock_supply.confirmation.qty_received_question = Enter the quantity received\ncht-stock-monitoring-workflow.stock_supply.tasks.stock-descreptancy = Commodity Discrepancy Resolution\n' + +'cht-stock-monitoring-workflow.stock_supply.forms.select_items = Select the different item you want to supply\ncht-stock-monitoring-workflow.stock_supply.confirmation.summary_note = Stock items you received.\n' + +'cht-stock-monitoring-workflow.stock_supply.discrepancy.summary_header = Results/Summary page\ncht-stock-monitoring-workflow.stock_supply.discrepancy.submit_note =

Be sure you Submit to complete this action.

\n' + +'cht-stock-monitoring-workflow.stock_supply.discrepancy.summary_note = Discrepancy resolution\ncht-stock-monitoring-workflow.stock_supply.discrepancy.quantity_issued = Quantity issued: {{qty}}\n' + +'cht-stock-monitoring-workflow.stock_supply.discrepancy.quantity_confirmed = Quantity confirmed: {{qty}}\ncht-stock-monitoring-workflow.stock_supply.discrepancy.quantity_final = What is the final quantity ?\n' + +'cht-stock-monitoring-workflow.stock_supply.label.confirm_qty = Confirm quantities\ncht-stock-monitoring-workflow.stock_supply.message.set_unit_constraint_message = Should be in the form x/y for x {{set_label}} and y {{unit_label}}\ncht-stock-monitoring-workflow.stock_supply.message.unit_quantity_hint = Add the quantity: {{quantity}} {{unit_label}}'; + + const frMessage = 'cht-stock-monitoring-workflow.stock_supply.page_1.header = Sélectionner les élément à livrer\n'+ + 'cht-stock-monitoring-workflow.stock_supply.forms.select_category = Sélectionner les catégories des éléments à retourner\n'+ + 'cht-stock-monitoring-workflow.stock_supply.page_1.select_input = Sélectionner\n'+ + 'cht-stock-monitoring-workflow.stock_supply.page_1.select_input_hint = Sélectionner tous les éléments à livrer\n'+ + 'cht-stock-monitoring-workflow.stock_supply.item.stock_on_hand = Stock actuel\n'+ + 'cht-stock-monitoring-workflow.stock_supply.item.quantity_of = Quantité de\n'+ + 'cht-stock-monitoring-workflow.stock_supply.summary_header = Page Résultats\n'+ + 'cht-stock-monitoring-workflow.stock_supply.submit_note =

Assurez-vous de soumettre pour enregistrer cette action.

\n'+ + 'cht-stock-monitoring-workflow.stock_supply.summary_note = Stock livré.\n'+ + 'cht-stock-monitoring-workflow.stock_supply.tasks.reception-confirmation = Stock reçu\n'+ + 'cht-stock-monitoring-workflow.stock_supply.confirmation.item_received_confirmation_question = Avez-vous reçu {{qty_unit}}\n'+ + 'cht-stock-monitoring-workflow.stock_supply.choices.yes_no.yes = Oui\n'+ + 'cht-stock-monitoring-workflow.stock_supply.choices.yes_no.no = Non\n'+ + 'cht-stock-monitoring-workflow.stock_supply.forms.additional_doc_title = Stock utilsé\n'+ + 'cht-stock-monitoring-workflow.stock_supply.forms.item_used_question = Quantité de {{item}}\n'+ + 'cht-stock-monitoring-workflow.stock_supply.confirmation.qty_received_question = Entrer la quantité reçu\n'+ + 'cht-stock-monitoring-workflow.stock_supply.tasks.stock-descreptancy = Résolution Conflit\n'+ + 'cht-stock-monitoring-workflow.stock_supply.forms.select_items = Sélectionner les différents éléments que vous voulez livrer\n'+ + 'cht-stock-monitoring-workflow.stock_supply.confirmation.summary_note = Stock que vous avez reçu.\n'+ + 'cht-stock-monitoring-workflow.stock_supply.discrepancy.summary_header = Page Résultats\n'+ + 'cht-stock-monitoring-workflow.stock_supply.discrepancy.submit_note =

Assurez-vous de soumettre pour completer cette action.

\n'+ + 'cht-stock-monitoring-workflow.stock_supply.discrepancy.summary_note = Résolution de conflits\n'+ + 'cht-stock-monitoring-workflow.stock_supply.discrepancy.quantity_issued = Quantité envoyée: {{qty}}\n'+ + 'cht-stock-monitoring-workflow.stock_supply.discrepancy.quantity_confirmed = Quantité confirmée: {{qty}}\n'+ + 'cht-stock-monitoring-workflow.stock_supply.discrepancy.quantity_final = Quelle est la quantité finale ?\n'+ + 'cht-stock-monitoring-workflow.stock_supply.label.confirm_qty = Confirmer les quantités\n'+ + 'cht-stock-monitoring-workflow.stock_supply.message.set_unit_constraint_message = Should be in the form x/y for x {{set_label}} and y {{unit_label}}\n'+ + 'cht-stock-monitoring-workflow.stock_supply.message.unit_quantity_hint = Add the quantity: {{quantity}} {{unit_label}}'; + + + beforeEach(async () => { + setDirToprojectConfig(); + await writeTranslationMessages(frMessage, enMessage, process.cwd()); + }); + + afterEach(async() => { + jest.clearAllMocks(); + await resetTranslationMessages(process.cwd()); + await cleanUp(workingDir, createdAppFiles); + revertBackToProjectHome(workingDir); + process.argv = processInitialArgv; // Restore the original argv after each test + }); + + + // Testing get item row function + it('This should throw error and should not generate rows with empty header, messages, languages(fr, en) and items to be added ', async () => { + + const header = []; + const messages = {}; + const items = [{}]; + + expect(() => getItemRows(header, stockMonitoringConfigs.languages, messages, items)).toThrow(TypeError); + + }); + + it('This should return rows with header, messages, languages(fr, en) and items to be added ', async () => { + + const header = [ + 'type', + 'name', + 'required', + 'relevant', + 'appearance', + 'constraint', + 'constraint_message', + 'calculation', + 'default', + 'label::en', + 'label::fr', + 'hint:en', + 'hint:fr' + ]; + + const messages = getTranslations(); + const items = Object.values(stockMonitoringConfigs.items); + + const row = getItemRows(header, stockMonitoringConfigs.languages, messages, items); + expect(row).not.toEqual([]); + expect(row.length).toBe(items.length); + const oneRow = row[0][0]; + expect(oneRow.length).toBe(13); + expect(oneRow[0]).toEqual('begin group'); + expect(oneRow[1]).toContain(items[0].name); + + }); + + /** Testing add confirmation calculation to stock_supply */ + it('should add stock supply calculation correctly with items provided', async () => { + const items = Object.values(stockMonitoringConfigs.items); + const projectDataDir = process.cwd(); + const messages = getTranslations(); + + // Call the function updateStockSupply and check that the stock_order files are generated + await updateStockSupply(stockMonitoringConfigs, messages); + + const formPath = path.join(projectDataDir, 'forms', 'app', 'stock_supply.xlsx'); + const workbook = new ExcelJS.Workbook(); + await workbook.xlsx.readFile(formPath); + const surveyWorkSheet = workbook.getWorksheet('survey'); + + addStockSupplyCalculation(surveyWorkSheet, items); + + // Check that items are inserted in stock_return xform + const itemData = items.map(item => `${item.name}_supply`); + const stockSupplyData = await readDataFromXforms([], itemData, 'stock_supply.xlsx' ); + + expect(stockSupplyData.productsList.length).toBe(itemData.length); + for(let index =0; index < itemData.length; index ++){ + expect(stockSupplyData.productsList[index]).toEqual(itemData[index]); + } + + }); + + /** Testing add summaries to stock_supply */ + it('should add summaries correctly when categories and items are provided', async () => { + const languages = Object.values(stockMonitoringConfigs.languages); + const items = Object.values(stockMonitoringConfigs.items); + const projectDataDir = process.cwd(); + const messages = getTranslations(); + + // Call the function updateStockSupply and check that the stock_supply files are generated + await updateStockSupply(stockMonitoringConfigs, messages); + + const formPath = path.join(projectDataDir, 'forms', 'app', 'stock_supply.xlsx'); + const workbook = new ExcelJS.Workbook(); + await workbook.xlsx.readFile(formPath); + const surveyWorkSheet = workbook.getWorksheet('survey'); + + addStockSupplySummaries(surveyWorkSheet, items, languages); + + // Check that items are inserted in stock_supply xform + const categoryNames = []; + const itemNames =items.map(item => `s_${item.name}`); + const stockOrderData = await readDataFromXforms(categoryNames, itemNames,'stock_supply.xlsx' ); + + expect(stockOrderData.productsList.length).toBe(itemNames.length); + expect(stockOrderData.productsList.entries).toStrictEqual(itemNames.entries); + expect(stockOrderData.productCategoryList.length).toBe(categoryNames.length); + expect(stockOrderData.productCategoryList.entries).toStrictEqual(categoryNames.entries); + + }); + + // Testing get additional doc + it('This should return additional doc for stock discrepancy', async () => { + const header = [ + 'type', + 'name', + 'required', + 'relevant', + 'appearance', + 'constraint', + 'constraint_message', + 'calculation', + 'default', + 'label::en', + 'label::fr', + 'hint:en', + 'hint:fr' + ]; + + const items = Object.values(stockMonitoringConfigs.items); + const languages = Object.values(stockMonitoringConfigs.languages); + const form_name = stockMonitoringConfigs.features.stock_supply.discrepancy.form_name; + const needsConfirmation = stockMonitoringConfigs.features.stock_supply.confirm_supply.active; + + const itemCalculation = [ + 'calculate', + 'paracetamol_in', + '', + '', + '', + '', + '', + '${paracetamol___count}', + '', + '', + '', + '', + '' + ]; + + const additionalDoc = getAdditionalDoc(form_name, languages, header, items, needsConfirmation); + expect(additionalDoc).toContainEqual(itemCalculation); + + }); + + /** Testing getStockSupplyConfigs function */ + // Testing stock supply config generation with correct item config + it('This should generate stock supply config configurations based the item config provided ', async () => { + process.argv = ['', '', '','', + 'stock_supply', 'Stock Supply,Apporvisionnement de stock', + true, 'stock_received','Stock Received, Stock Reçu', + 'stock_discrepancy_resolution', + 'Stock Discrepancy Resolution, Resolution de Stock' + ]; + const configs = { + form_name: 'stock_supply', + title: { en: 'Stock Supply', fr: 'Apporvisionnement de stock' }, + confirm_supply: { + form_name: 'stock_received', + title: { + en: 'Stock Received', + fr: ' Stock Reçu' + }, + active: true + }, + discrepancy: { + form_name: 'stock_discrepancy_resolution', + title: { + en: 'Stock Discrepancy Resolution', + fr: ' Resolution de Stock' + } + } + }; + + const featureConfigs = await getStockSupplyConfigs(stockMonitoringConfigs); + expect(featureConfigs).toEqual(configs); + + }); + + it('This should throw error for xform configurations with no or wrong item config', async () => { + await expect(getStockSupplyConfigs(mockConfigsWithNoFeauture)).rejects.toThrow(Error); + }); + +}); diff --git a/test/stock-supply-feature.spec.js b/test/stock-supply-feature.spec.js index 70e6deb..b36fd92 100644 --- a/test/stock-supply-feature.spec.js +++ b/test/stock-supply-feature.spec.js @@ -1,27 +1,74 @@ const fs = require('fs'); const path = require('path'); -const { stockSupplyConfig, mockConfigsWithNoFeauture } = require('./mocks/mocks'); +const ExcelJS = require('exceljs'); +const { + stockMonitoringConfigs, + mockConfigsWithNoFeauture +} = require('./mocks/mocks'); const { updateStockSupply } = require('../src/features/stock-supply'); const { setDirToprojectConfig, revertBackToProjectHome, - readOutputFiles, - cleanUp + cleanUp, + writeTranslationMessages, + resetTranslationMessages } = require('./test-utils'); describe('update Stock Supply', () => { const workingDir = process.cwd(); const createdAppFormFiles = ['stock_supply.xlsx', 'stock_supply.properties.json']; + const enMessage = 'cht-stock-monitoring-workflow.stock_supply.page_1.header = Select item to supply\ncht-stock-monitoring-workflow.stock_supply.forms.select_category = Select the category of what you want to return\n' + +'cht-stock-monitoring-workflow.stock_supply.page_1.select_input = Select\ncht-stock-monitoring-workflow.stock_supply.page_1.select_input_hint = Select all items to supply\ncht-stock-monitoring-workflow.stock_supply.item.stock_on_hand = Stock on hand\ncht-stock-monitoring-workflow.stock_supply.item.quantity_of = Quantity of\n' + +'cht-stock-monitoring-workflow.stock_supply.summary_header = Results/Summary page\ncht-stock-monitoring-workflow.stock_supply.submit_note =

Be sure you Submit to complete this action.

\n' + +'cht-stock-monitoring-workflow.stock_supply.summary_note = Stock items you supply.\ncht-stock-monitoring-workflow.stock_supply.tasks.reception-confirmation = Stock received\n' + +'cht-stock-monitoring-workflow.stock_supply.confirmation.item_received_confirmation_question = Did you received {{qty_unit}}\ncht-stock-monitoring-workflow.stock_supply.choices.yes_no.yes = Yes\n' + +'cht-stock-monitoring-workflow.stock_supply.choices.yes_no.no = No\ncht-stock-monitoring-workflow.stock_supply.forms.additional_doc_title = Stock uses\ncht-stock-monitoring-workflow.stock_supply.forms.item_used_question = Quantity of {{item}}\n' + +'cht-stock-monitoring-workflow.stock_supply.confirmation.qty_received_question = Enter the quantity received\ncht-stock-monitoring-workflow.stock_supply.tasks.stock-descreptancy = Commodity Discrepancy Resolution\n' + +'cht-stock-monitoring-workflow.stock_supply.forms.select_items = Select the different item you want to supply\ncht-stock-monitoring-workflow.stock_supply.confirmation.summary_note = Stock items you received.\n' + +'cht-stock-monitoring-workflow.stock_supply.discrepancy.summary_header = Results/Summary page\ncht-stock-monitoring-workflow.stock_supply.discrepancy.submit_note =

Be sure you Submit to complete this action.

\n' + +'cht-stock-monitoring-workflow.stock_supply.discrepancy.summary_note = Discrepancy resolution\ncht-stock-monitoring-workflow.stock_supply.discrepancy.quantity_issued = Quantity issued: {{qty}}\n' + +'cht-stock-monitoring-workflow.stock_supply.discrepancy.quantity_confirmed = Quantity confirmed: {{qty}}\ncht-stock-monitoring-workflow.stock_supply.discrepancy.quantity_final = What is the final quantity ?\n' + +'cht-stock-monitoring-workflow.stock_supply.label.confirm_qty = Confirm quantities\ncht-stock-monitoring-workflow.stock_supply.message.set_unit_constraint_message = Should be in the form x/y for x {{set_label}} and y {{unit_label}}\ncht-stock-monitoring-workflow.stock_supply.message.unit_quantity_hint = Add the quantity: {{quantity}} {{unit_label}}'; + + const frMessage = 'cht-stock-monitoring-workflow.stock_supply.page_1.header = Sélectionner les élément à livrer\n'+ + 'cht-stock-monitoring-workflow.stock_supply.forms.select_category = Sélectionner les catégories des éléments à retourner\n'+ + 'cht-stock-monitoring-workflow.stock_supply.page_1.select_input = Sélectionner\n'+ + 'cht-stock-monitoring-workflow.stock_supply.page_1.select_input_hint = Sélectionner tous les éléments à livrer\n'+ + 'cht-stock-monitoring-workflow.stock_supply.item.stock_on_hand = Stock actuel\n'+ + 'cht-stock-monitoring-workflow.stock_supply.item.quantity_of = Quantité de\n'+ + 'cht-stock-monitoring-workflow.stock_supply.summary_header = Page Résultats\n'+ + 'cht-stock-monitoring-workflow.stock_supply.submit_note =

Assurez-vous de soumettre pour enregistrer cette action.

\n'+ + 'cht-stock-monitoring-workflow.stock_supply.summary_note = Stock livré.\n'+ + 'cht-stock-monitoring-workflow.stock_supply.tasks.reception-confirmation = Stock reçu\n'+ + 'cht-stock-monitoring-workflow.stock_supply.confirmation.item_received_confirmation_question = Avez-vous reçu {{qty_unit}}\n'+ + 'cht-stock-monitoring-workflow.stock_supply.choices.yes_no.yes = Oui\n'+ + 'cht-stock-monitoring-workflow.stock_supply.choices.yes_no.no = Non\n'+ + 'cht-stock-monitoring-workflow.stock_supply.forms.additional_doc_title = Stock utilsé\n'+ + 'cht-stock-monitoring-workflow.stock_supply.forms.item_used_question = Quantité de {{item}}\n'+ + 'cht-stock-monitoring-workflow.stock_supply.confirmation.qty_received_question = Entrer la quantité reçu\n'+ + 'cht-stock-monitoring-workflow.stock_supply.tasks.stock-descreptancy = Résolution Conflit\n'+ + 'cht-stock-monitoring-workflow.stock_supply.forms.select_items = Sélectionner les différents éléments que vous voulez livrer\n'+ + 'cht-stock-monitoring-workflow.stock_supply.confirmation.summary_note = Stock que vous avez reçu.\n'+ + 'cht-stock-monitoring-workflow.stock_supply.discrepancy.summary_header = Page Résultats\n'+ + 'cht-stock-monitoring-workflow.stock_supply.discrepancy.submit_note =

Assurez-vous de soumettre pour completer cette action.

\n'+ + 'cht-stock-monitoring-workflow.stock_supply.discrepancy.summary_note = Résolution de conflits\n'+ + 'cht-stock-monitoring-workflow.stock_supply.discrepancy.quantity_issued = Quantité envoyée: {{qty}}\n'+ + 'cht-stock-monitoring-workflow.stock_supply.discrepancy.quantity_confirmed = Quantité confirmée: {{qty}}\n'+ + 'cht-stock-monitoring-workflow.stock_supply.discrepancy.quantity_final = Quelle est la quantité finale ?\n'+ + 'cht-stock-monitoring-workflow.stock_supply.label.confirm_qty = Confirmer les quantités\n'+ + 'cht-stock-monitoring-workflow.stock_supply.message.set_unit_constraint_message = Should be in the form x/y for x {{set_label}} and y {{unit_label}}\n'+ + 'cht-stock-monitoring-workflow.stock_supply.message.unit_quantity_hint = Add the quantity: {{quantity}} {{unit_label}}'; - beforeEach(() => { + beforeEach(async() => { setDirToprojectConfig(); + await writeTranslationMessages(frMessage, enMessage, process.cwd()); }); afterEach(async () => { // Remove the generated files - await cleanUp(workingDir, createdAppFormFiles); + await resetTranslationMessages(process.cwd()); revertBackToProjectHome(workingDir); - jest.clearAllMocks(); + await cleanUp(workingDir, createdAppFormFiles); }); it('should not generate and update stock supply form', async () => { @@ -44,14 +91,16 @@ describe('update Stock Supply', () => { expect(fs.existsSync(path.join(processDir, 'forms', 'app', createdAppFormFile))).toBe(false); } // Call the function updateStockSupply and check that the stock_supply files are generated - await updateStockSupply(stockSupplyConfig); + await updateStockSupply(stockMonitoringConfigs); for(const createdAppFormFile of createdAppFormFiles){ expect(fs.existsSync(path.join(processDir, 'forms', 'app', createdAppFormFile))).toBe(true); } // Check that stock supply files content are correctly written. - const {workbook, propertiesFileContent} = await readOutputFiles(createdAppFormFiles); + const formPath = path.join(processDir, 'forms', 'app', 'stock_supply.xlsx'); + const workbook = new ExcelJS.Workbook(); + await workbook.xlsx.readFile(formPath); const spy = jest.spyOn(workbook, 'getWorksheet'); const surveyWorkSheet = workbook.getWorksheet('survey'); expect(spy).toHaveBeenCalledTimes(1); @@ -62,6 +111,11 @@ describe('update Stock Supply', () => { expect(surveyWorkSheet).not.toEqual([]); expect(settingWorkSheet).not.toEqual([]); + const propertiesFileContent = fs.readFileSync( + path.join(processDir, 'forms', 'app', 'stock_supply.properties.json'), + {encoding: 'utf-8'} + ); + expect(JSON.parse(propertiesFileContent)).toEqual({ 'context': { 'expression': 'contact.contact_type === \'c62_chw_site\' && user.parent.contact_type === \'c50_supervision_area\' && user.role === \'supervisor\'', diff --git a/test/stock-supply-integration.spec.js b/test/stock-supply-integration.spec.js index cea2e4d..44931c2 100644 --- a/test/stock-supply-integration.spec.js +++ b/test/stock-supply-integration.spec.js @@ -1,33 +1,78 @@ const { spawnSync } = require('child_process'); const path = require('path'); const fs = require('fs-extra'); +const ExcelJS = require('exceljs'); const { stockSupplyScenario, - stockCountScenario + stockCountScenario, + stockMonitoringScenario } = require('./mocks/mocks'); const { setDirToprojectConfig, revertBackToProjectHome, cleanUp, - readOutputFiles, - readDataFromXforms + readDataFromXforms, + writeTranslationMessages, + resetTranslationMessages } = require('./test-utils'); describe('Stock supply integration test', () => { const workingDir = process.cwd(); const createdAppFormFiles = [ 'stock_count.xlsx', 'stock_count.properties.json', 'stock_supply.xlsx', 'stock_supply.properties.json', 'stock_received.xlsx', 'stock_received.properties.json', 'stock_discrepancy_resolution.xlsx', 'stock_discrepancy_resolution.properties.json']; - - beforeEach(() => { + const enMessage = 'cht-stock-monitoring-workflow.stock_supply.page_1.header = Select item to supply\ncht-stock-monitoring-workflow.stock_supply.forms.select_category = Select the category of what you want to return\n' + +'cht-stock-monitoring-workflow.stock_supply.page_1.select_input = Select\ncht-stock-monitoring-workflow.stock_supply.page_1.select_input_hint = Select all items to supply\ncht-stock-monitoring-workflow.stock_supply.item.stock_on_hand = Stock on hand\ncht-stock-monitoring-workflow.stock_supply.item.quantity_of = Quantity of\n' + +'cht-stock-monitoring-workflow.stock_supply.summary_header = Results/Summary page\ncht-stock-monitoring-workflow.stock_supply.submit_note =

Be sure you Submit to complete this action.

\n' + +'cht-stock-monitoring-workflow.stock_supply.summary_note = Stock items you supply.\ncht-stock-monitoring-workflow.stock_supply.tasks.reception-confirmation = Stock received\n' + +'cht-stock-monitoring-workflow.stock_supply.confirmation.item_received_confirmation_question = Did you received {{qty_unit}}\ncht-stock-monitoring-workflow.stock_supply.choices.yes_no.yes = Yes\n' + +'cht-stock-monitoring-workflow.stock_supply.choices.yes_no.no = No\ncht-stock-monitoring-workflow.stock_supply.forms.additional_doc_title = Stock uses\ncht-stock-monitoring-workflow.stock_supply.forms.item_used_question = Quantity of {{item}}\n' + +'cht-stock-monitoring-workflow.stock_supply.confirmation.qty_received_question = Enter the quantity received\ncht-stock-monitoring-workflow.stock_supply.tasks.stock-descreptancy = Commodity Discrepancy Resolution\n' + +'cht-stock-monitoring-workflow.stock_supply.forms.select_items = Select the different item you want to supply\ncht-stock-monitoring-workflow.stock_supply.confirmation.summary_note = Stock items you received.\n' + +'cht-stock-monitoring-workflow.stock_supply.discrepancy.summary_header = Results/Summary page\ncht-stock-monitoring-workflow.stock_supply.discrepancy.submit_note =

Be sure you Submit to complete this action.

\n' + +'cht-stock-monitoring-workflow.stock_supply.discrepancy.summary_note = Discrepancy resolution\ncht-stock-monitoring-workflow.stock_supply.discrepancy.quantity_issued = Quantity issued: {{qty}}\n' + +'cht-stock-monitoring-workflow.stock_supply.discrepancy.quantity_confirmed = Quantity confirmed: {{qty}}\ncht-stock-monitoring-workflow.stock_supply.discrepancy.quantity_final = What is the final quantity ?\n' + +'cht-stock-monitoring-workflow.stock_supply.label.confirm_qty = Confirm quantities\ncht-stock-monitoring-workflow.stock_supply.message.set_unit_constraint_message = Should be in the form x/y for x {{set_label}} and y {{unit_label}}\ncht-stock-monitoring-workflow.stock_supply.message.unit_quantity_hint = Add the quantity: {{quantity}} {{unit_label}}'; + + const frMessage = 'cht-stock-monitoring-workflow.stock_supply.page_1.header = Sélectionner les élément à livrer\n'+ + 'cht-stock-monitoring-workflow.stock_supply.forms.select_category = Sélectionner les catégories des éléments à retourner\n'+ + 'cht-stock-monitoring-workflow.stock_supply.page_1.select_input = Sélectionner\n'+ + 'cht-stock-monitoring-workflow.stock_supply.page_1.select_input_hint = Sélectionner tous les éléments à livrer\n'+ + 'cht-stock-monitoring-workflow.stock_supply.item.stock_on_hand = Stock actuel\n'+ + 'cht-stock-monitoring-workflow.stock_supply.item.quantity_of = Quantité de\n'+ + 'cht-stock-monitoring-workflow.stock_supply.summary_header = Page Résultats\n'+ + 'cht-stock-monitoring-workflow.stock_supply.submit_note =

Assurez-vous de soumettre pour enregistrer cette action.

\n'+ + 'cht-stock-monitoring-workflow.stock_supply.summary_note = Stock livré.\n'+ + 'cht-stock-monitoring-workflow.stock_supply.tasks.reception-confirmation = Stock reçu\n'+ + 'cht-stock-monitoring-workflow.stock_supply.confirmation.item_received_confirmation_question = Avez-vous reçu {{qty_unit}}\n'+ + 'cht-stock-monitoring-workflow.stock_supply.choices.yes_no.yes = Oui\n'+ + 'cht-stock-monitoring-workflow.stock_supply.choices.yes_no.no = Non\n'+ + 'cht-stock-monitoring-workflow.stock_supply.forms.additional_doc_title = Stock utilsé\n'+ + 'cht-stock-monitoring-workflow.stock_supply.forms.item_used_question = Quantité de {{item}}\n'+ + 'cht-stock-monitoring-workflow.stock_supply.confirmation.qty_received_question = Entrer la quantité reçu\n'+ + 'cht-stock-monitoring-workflow.stock_supply.tasks.stock-descreptancy = Résolution Conflit\n'+ + 'cht-stock-monitoring-workflow.stock_supply.forms.select_items = Sélectionner les différents éléments que vous voulez livrer\n'+ + 'cht-stock-monitoring-workflow.stock_supply.confirmation.summary_note = Stock que vous avez reçu.\n'+ + 'cht-stock-monitoring-workflow.stock_supply.discrepancy.summary_header = Page Résultats\n'+ + 'cht-stock-monitoring-workflow.stock_supply.discrepancy.submit_note =

Assurez-vous de soumettre pour completer cette action.

\n'+ + 'cht-stock-monitoring-workflow.stock_supply.discrepancy.summary_note = Résolution de conflits\n'+ + 'cht-stock-monitoring-workflow.stock_supply.discrepancy.quantity_issued = Quantité envoyée: {{qty}}\n'+ + 'cht-stock-monitoring-workflow.stock_supply.discrepancy.quantity_confirmed = Quantité confirmée: {{qty}}\n'+ + 'cht-stock-monitoring-workflow.stock_supply.discrepancy.quantity_final = Quelle est la quantité finale ?\n'+ + 'cht-stock-monitoring-workflow.stock_supply.label.confirm_qty = Confirmer les quantités\n'+ + 'cht-stock-monitoring-workflow.stock_supply.message.set_unit_constraint_message = Should be in the form x/y for x {{set_label}} and y {{unit_label}}\n'+ + 'cht-stock-monitoring-workflow.stock_supply.message.unit_quantity_hint = Add the quantity: {{quantity}} {{unit_label}}'; + + beforeEach(async() => { setDirToprojectConfig(); + await writeTranslationMessages(frMessage, enMessage, process.cwd()); }); afterEach(async() => { // Remove the generated files await cleanUp(workingDir, createdAppFormFiles); + await resetTranslationMessages(process.cwd()); revertBackToProjectHome(workingDir); - jest.clearAllMocks(); }); it('Add stock out integration test', async() => { @@ -38,7 +83,7 @@ describe('Stock supply integration test', () => { } // Initializing stock monitoring - const childProcess = await spawnSync('../../main.js', stockSupplyScenario.initScenario); + const childProcess = await spawnSync('../../main.js', stockMonitoringScenario.initScenario); if (childProcess.error) { throw childProcess.error; @@ -60,11 +105,17 @@ describe('Stock supply integration test', () => { expect(fs.existsSync(path.join(processDir, 'stock-monitoring.config.json'))).toBe(true); // Check that stock count files content are correctly written. - const {workbook, propertiesFileContent} = await readOutputFiles(['stock_count.xlsx', 'stock_count.properties.json']); + let formPath = path.join(processDir, 'forms', 'app', 'stock_count.xlsx'); + const workbook = new ExcelJS.Workbook(); + await workbook.xlsx.readFile(formPath); let surveyWorkSheet = workbook.getWorksheet('survey'); let settingWorkSheet = workbook.getWorksheet('settings'); expect(surveyWorkSheet._name).toEqual('survey'); expect(settingWorkSheet._name).toEqual('settings'); + let propertiesFileContent = fs.readFileSync( + path.join(processDir, 'forms', 'app', 'stock_received.properties.json'), + {encoding: 'utf-8'} + ); expect(propertiesFileContent).not.toEqual([]); // Check that the products are available in stock count xform @@ -76,27 +127,45 @@ describe('Stock supply integration test', () => { expect(productsList.entries).toStrictEqual(stockCountScenario.productsScenario.entries); // Check that stock Supply files content are correctly written. - const stockSupplyWorkbook = await readOutputFiles(['stock_supply.xlsx', 'stock_supply.properties.json']); - surveyWorkSheet = stockSupplyWorkbook.workbook.getWorksheet('survey'); - settingWorkSheet = stockSupplyWorkbook.workbook.getWorksheet('settings'); + formPath = path.join(processDir, 'forms', 'app', 'stock_supply.xlsx'); + const stockSupplyWorkbook = new ExcelJS.Workbook(); + await stockSupplyWorkbook.xlsx.readFile(formPath); + surveyWorkSheet = stockSupplyWorkbook.getWorksheet('survey'); + settingWorkSheet = stockSupplyWorkbook.getWorksheet('settings'); expect(surveyWorkSheet._name).toEqual('survey'); expect(settingWorkSheet._name).toEqual('settings'); + propertiesFileContent = fs.readFileSync( + path.join(processDir, 'forms', 'app', 'stock_supply.properties.json'), + {encoding: 'utf-8'} + ); expect(stockSupplyWorkbook.propertiesFileContent).not.toEqual([]); // Check that stock Received files content are correctly written. - const stockReceivedWorkbook = await readOutputFiles(['stock_supply.xlsx', 'stock_supply.properties.json']); - surveyWorkSheet = stockReceivedWorkbook.workbook.getWorksheet('survey'); - settingWorkSheet = stockReceivedWorkbook.workbook.getWorksheet('settings'); + formPath = path.join(processDir, 'forms', 'app', 'stock_received.xlsx'); + const stockReceivedWorkbook = new ExcelJS.Workbook(); + await stockReceivedWorkbook.xlsx.readFile(formPath); + surveyWorkSheet = stockReceivedWorkbook.getWorksheet('survey'); + settingWorkSheet = stockReceivedWorkbook.getWorksheet('settings'); expect(surveyWorkSheet._name).toEqual('survey'); expect(settingWorkSheet._name).toEqual('settings'); + propertiesFileContent = fs.readFileSync( + path.join(processDir, 'forms', 'app', 'stock_received.properties.json'), + {encoding: 'utf-8'} + ); expect(stockReceivedWorkbook.propertiesFileContent).not.toEqual([]); // Check that stock Discrepancy files content are correctly written. - const stockDiscrepancyWorkbook = await readOutputFiles(['stock_discrepancy_resolution.xlsx', 'stock_discrepancy_resolution.properties.json']); - surveyWorkSheet = stockDiscrepancyWorkbook.workbook.getWorksheet('survey'); - settingWorkSheet = stockDiscrepancyWorkbook.workbook.getWorksheet('settings'); + formPath = path.join(processDir, 'forms', 'app', 'stock_discrepancy_resolution.xlsx'); + const stockDiscrepancyWorkbook = new ExcelJS.Workbook(); + await stockDiscrepancyWorkbook.xlsx.readFile(formPath); + surveyWorkSheet = stockDiscrepancyWorkbook.getWorksheet('survey'); + settingWorkSheet = stockDiscrepancyWorkbook.getWorksheet('settings'); expect(surveyWorkSheet._name).toEqual('survey'); expect(settingWorkSheet._name).toEqual('settings'); + propertiesFileContent = fs.readFileSync( + path.join(processDir, 'forms', 'app', 'stock_discrepancy_resolution.properties.json'), + {encoding: 'utf-8'} + ); expect(stockDiscrepancyWorkbook.propertiesFileContent).not.toEqual([]); } diff --git a/test/test-utils.js b/test/test-utils.js index 5c35c52..6d28f2b 100644 --- a/test/test-utils.js +++ b/test/test-utils.js @@ -16,7 +16,7 @@ const revertBackToProjectHome = (projectHome) =>{ process.chdir(projectHome); }; -const cleanUp = (workingDir, fileNames) => { +const cleanUp = async(workingDir, fileNames) => { const processDir = path.join(workingDir,'test/project-config/'); for(const formFile of fileNames){ const filePath = path.join(processDir, 'forms', 'app', formFile);