Skip to content

Commit

Permalink
Add others tests, refactor code and error throws
Browse files Browse the repository at this point in the history
  • Loading branch information
obieler committed Jul 5, 2023
1 parent cd15c21 commit 172aa3e
Show file tree
Hide file tree
Showing 6 changed files with 119 additions and 129 deletions.
2 changes: 1 addition & 1 deletion src/controllers/unit.controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ async function get (req, res) {
const results = await unitService.get(req.query);
return res.json(results);
} catch (err) {
console.error('[error] ', err.message);
console.error('[error] ', err);
return res.status(400).json({
success: false,
error: 'Oops, something went wrong'
Expand Down
5 changes: 1 addition & 4 deletions src/services/cadidb.service.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,12 @@ const cadidbConfig = require('../configs/cadidb.config');

const pool = mysql.createPool(cadidbConfig.db);

async function sendQuery (query, values, referrer = 'default') {
async function sendQuery (query, values, referrer) {
let connection;
try {
connection = await pool.getConnection();
const [rows] = await connection.query(query, values, referrer);
return rows;
} catch (err) {
console.error('Error executing query', err);
return err;
} finally {
if (connection) {
connection.release();
Expand Down
158 changes: 71 additions & 87 deletions src/services/unit.service.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,20 +25,16 @@ async function searchUnits (q, lang) {
'(sigle like ? OR libelle like ? OR libelle_en like ?)';
const values = ['Z', '%' + q + '%', '%' + q + '%', '%' + q + '%'];

try {
const results = await cadidbService.sendQuery(query, values, 'searchUnits');
const formattedResults = results.map((dict) => {
const modifiedDict = {
acronym: dict.sigle,
path: dict.hierarchie.split(' '),
name: lang === 'en' ? dict.libelle_en : dict.libelle
};
return modifiedDict;
});
return formattedResults;
} catch (err) {
console.error('Error: ', err);
}
const results = await cadidbService.sendQuery(query, values, 'searchUnits');
const formattedResults = results.map((dict) => {
const modifiedDict = {
acronym: dict.sigle,
path: dict.hierarchie.split(' '),
name: lang === 'en' ? dict.libelle_en : dict.libelle
};
return modifiedDict;
});
return formattedResults;
}

async function getUnit (acro, lang) {
Expand All @@ -50,57 +46,53 @@ async function getUnit (acro, lang) {
'WHERE sigle = ? AND cmpl_type <> ?';
const values = [acro, 'Z'];

try {
const results = await cadidbService.sendQuery(query, values, 'getUnit');
if (results.length !== 1) {
return;
}
const dict = results[0];
const unitPath = await getUnitPath(dict.hierarchie, lang);
const unitFullDetails = {
code: dict.id_unite,
acronym: dict.sigle,
name: lang === 'en' ? dict.libelle_en : dict.libelle,
unitPath: dict.hierarchie,
path: unitPath,
terminal: dict.has_accreds,
ghost: dict.ghost,
address: dict.adresse.split('$').map((value) => value.trim())
.filter((value) => value !== ''),
head: {
sciper: dict.resp_sciper,
name: dict.resp_nom_usuel || dict.resp_nom,
firstname: dict.resp_prenom_usuel || dict.resp_prenom,
email: '<EMAIL>', // TODO: Get email from ldap
profile: '<EMAIL_PREFIX>' // TODO: Build from email over
}
};
if (dict.url) {
unitFullDetails.url = dict.url;
const results = await cadidbService.sendQuery(query, values, 'getUnit');
if (results.length !== 1) {
return;
}
const dict = results[0];
const unitPath = await getUnitPath(dict.hierarchie, lang);
const unitFullDetails = {
code: dict.id_unite,
acronym: dict.sigle,
name: lang === 'en' ? dict.libelle_en : dict.libelle,
unitPath: dict.hierarchie,
path: unitPath,
terminal: dict.has_accreds,
ghost: dict.ghost,
address: dict.adresse.split('$').map((value) => value.trim())
.filter((value) => value !== ''),
head: {
sciper: dict.resp_sciper,
name: dict.resp_nom_usuel || dict.resp_nom,
firstname: dict.resp_prenom_usuel || dict.resp_prenom,
email: '<EMAIL>', // TODO: Get email from ldap
profile: '<EMAIL_PREFIX>' // TODO: Build from email over
}
if (dict.has_accreds) {
// TODO: Get people from ldap
};
if (dict.url) {
unitFullDetails.url = dict.url;
}
if (dict.has_accreds) {
// TODO: Get people from ldap

} else {
unitFullDetails.subunits = await getSubunits(dict.id_unite, lang);
}
if (dict.faxes) {
unitFullDetails.faxes = dict.faxes.split(',').map((fax) => {
const trimmedFax = fax.trim();
if (trimmedFax.startsWith('0')) {
return trimmedFax.replace(/^0(\d{2})(.*)/, '+41 $1 $2');
} else {
return '+41 21 69' + trimmedFax;
}
});
}
} else {
unitFullDetails.subunits = await getSubunits(dict.id_unite, lang);
}
if (dict.faxes) {
unitFullDetails.faxes = dict.faxes.split(',').map((fax) => {
const trimmedFax = fax.trim();
if (trimmedFax.startsWith('0')) {
return trimmedFax.replace(/^0(\d{2})(.*)/, '+41 $1 $2');
} else {
return '+41 21 69' + trimmedFax;
}
});
}

// TODO: if req.get('X-EPFL-Internal') === 'TRUE' → add `adminData`
// TODO: if req.get('X-EPFL-Internal') === 'TRUE' → add `adminData`

return unitFullDetails;
} catch (err) {
console.error('Error: ', err);
}
return unitFullDetails;
}

// Get unit path (acronym + name)
Expand All @@ -111,19 +103,15 @@ async function getUnitPath (hierarchy, lang) {
`WHERE sigle ${inHierarchyClause}`;
const values = [];

try {
const results = await cadidbService.sendQuery(query, values, 'getUnitPath');
const formattedResults = results.map((dict) => {
const modifiedDict = {
acronym: dict.sigle,
name: lang === 'en' ? dict.libelle_en : dict.libelle
};
return modifiedDict;
});
return formattedResults;
} catch (err) {
console.error('Error: ', err);
}
const results = await cadidbService.sendQuery(query, values, 'getUnitPath');
const formattedResults = results.map((dict) => {
const modifiedDict = {
acronym: dict.sigle,
name: lang === 'en' ? dict.libelle_en : dict.libelle
};
return modifiedDict;
});
return formattedResults;
}

// Get Subunit(s) (acronym + name)
Expand All @@ -133,19 +121,15 @@ async function getSubunits (unitId, lang) {
'WHERE id_parent = ? AND cmpl_type <> ?';
const values = [unitId, 'Z'];

try {
const results = await cadidbService.sendQuery(query, values, 'getSubunits');
const formattedResults = results.map((dict) => {
const modifiedDict = {
acronym: dict.sigle,
name: lang === 'en' ? dict.libelle_en : dict.libelle
};
return modifiedDict;
});
return formattedResults;
} catch (err) {
console.error('Error: ', err);
}
const results = await cadidbService.sendQuery(query, values, 'getSubunits');
const formattedResults = results.map((dict) => {
const modifiedDict = {
acronym: dict.sigle,
name: lang === 'en' ? dict.libelle_en : dict.libelle
};
return modifiedDict;
});
return formattedResults;
}

module.exports = {
Expand Down
37 changes: 2 additions & 35 deletions tests/cadidb.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,20 +13,6 @@ jest.mock('mysql2/promise', () => {
});

describe('Test Cadi DB Service', () => {
let testOutput = [];
const originalConsoleError = console.error;
const testConsoleError = (output) => { testOutput.push(output); };

beforeEach(() => {
jest.clearAllMocks();
console.error = testConsoleError;
testOutput = [];
});

afterEach(() => {
console.error = originalConsoleError;
});

test('It should execute the query and return the result', async () => {
const mockConnection = {
query: jest.fn().mockResolvedValue([[{ id: 1, name: 'Drebin' }]]),
Expand All @@ -37,30 +23,11 @@ describe('Test Cadi DB Service', () => {

const query = 'SELECT * FROM users';
const values = [];
const result = await cadidbService.sendQuery(query, values, 'default');
const result = await cadidbService.sendQuery(query, values, 'test');

expect(result).toEqual([{ id: 1, name: 'Drebin' }]);
expect(mysql.createPool).toHaveBeenCalled();
expect(mockConnection.query).toHaveBeenCalledWith(query, values, 'default');
expect(mockConnection.release).toHaveBeenCalled();
});

test('It should execute the query and return the result', async () => {
const mockConnection = {
query: jest.fn().mockRejectedValue(new Error('Error executing query')),
release: jest.fn()
};

mysql.createPool().getConnection.mockResolvedValue(mockConnection);

const query = 'SELECT * FROM users';
const values = [];
await cadidbService.sendQuery(query, values);

expect(mysql.createPool).toHaveBeenCalled();
expect(mockConnection.query).toHaveBeenCalledWith(query, values, 'default');
expect(mockConnection.query).toHaveBeenCalledWith(query, values, 'test');
expect(mockConnection.release).toHaveBeenCalled();
expect(testOutput.length).toBe(1);
expect(testOutput[0]).toMatch('Error executing query');
});
});
6 changes: 6 additions & 0 deletions tests/resources/cadidb/searchUnits-badJSON.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
[
{
"libelle": "Trilogie originale",
"libelle_en": "Original trilogy",
"hierarchie": "EPFL OT"
]
40 changes: 38 additions & 2 deletions tests/unit.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,16 +14,36 @@ jest.mock('mysql2/promise', () => {
});

describe('Test API Unit ("/api/unit")', () => {
let testOutput = [];
const originalConsoleError = console.error;
const testConsoleError = (output) => {
testOutput.push(output);
};

beforeEach(() => {
jest.clearAllMocks();
console.error = testConsoleError;
testOutput = [];
});

afterEach(() => {
console.error = originalConsoleError;
});

test('It should return nothing', async () => {
const mockConnection = {
query: jest.fn().mockResolvedValue([[]]),
release: jest.fn()
};
mysql.createPool().getConnection.mockResolvedValue(mockConnection);

const response = await request(app).get('/api/unit?q=drebin&hl=fr');
let response = await request(app).get('/api/unit?q=drebin&hl=fr');
expect(response.statusCode).toBe(200);
expect(JSON.parse(response.text)).toStrictEqual([]);

response = await request(app).get('/api/unit?acro=mandalo&hl=fr');
expect(response.statusCode).toBe(200);
expect(response.text).toBe('');
});

test('It should return a unit list', async () => {
Expand Down Expand Up @@ -104,7 +124,6 @@ describe('Test API Unit ("/api/unit")', () => {
break;
case 'getSubunits':
jsonData = require('./resources/cadidb/getSubunits-ot.json');
console.log(jsonData);
}
return Promise.resolve([jsonData]);
}),
Expand All @@ -122,4 +141,21 @@ describe('Test API Unit ("/api/unit")', () => {
expect(response.statusCode).toBe(200);
expect(JSON.parse(response.text)).toStrictEqual(jsonResult);
});

test('It should return a error with a status code 400', async () => {
const mockConnection = {
query: jest.fn().mockImplementation((query, values) => {
const jsonData = require('./resources/cadidb/searchUnits-badJSON.json');
return Promise.resolve([jsonData]);
}),
release: jest.fn()
};
mysql.createPool().getConnection.mockResolvedValue(mockConnection);

const response = await request(app).get('/api/unit?q=xxx&hl=en');
expect(response.statusCode).toBe(400);
expect(response.text).toMatch('Oops, something went wrong');
expect(testOutput.length).toBe(1);
expect(testOutput[0]).toMatch('error');
});
});

0 comments on commit 172aa3e

Please sign in to comment.