Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Question service improvements #351

Merged
merged 10 commits into from
Apr 28, 2024
17 changes: 7 additions & 10 deletions questions/__tests/services/question-generation-service.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ const generalQuestions = require('../../utils/generalQuestions');
jest.mock('../../utils/generalQuestions');
jest.mock('../../services/wikidata-service');
jest.mock('../../services/question-data-service', () => ({
getQuestion: jest.fn(),
addQuestion: jest.fn(), // Mockear la función addQuestion para que no haga nada
}));

Expand All @@ -15,15 +16,10 @@ const entity = {
"properties": [
{
"property": "P1082",
"template":
[{
"lang": "es",
"question": "Cuál es la población de x"
},
{
"lang": "en",
"question": "What is the population of x"
}],
"template": {
"es": "Cuál es la población de x",
"en": "What is the population of x"
},
"filter": ">1000000",
"category": ["Geography"]
}
Expand All @@ -48,8 +44,9 @@ describe('Question generation', function() {
wikidataService.getProperties.mockResolvedValue(['Barcelona', 'Paris', 'London']);
wikidataService.convertUrlsToLabels.mockResolvedValue(['Barcelona', 'Paris', 'London','Madrid']);

generalQuestions.shuffleArray.mockResolvedValue(['Barcelona', 'Paris', 'London','Madrid'])
generalQuestions.shuffleArray.mockResolvedValue(['Barcelona', 'Paris', 'London','Madrid']);

dbService.getQuestion.mockResolvedValue("undefined");
dbService.addQuestion.mockResolvedValue();
// Llama a la función que deseas probar
await generator.generateQuestions(1,"en","Geography");
Expand Down
48 changes: 42 additions & 6 deletions questions/services/generate-questions-service.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
const utils = require('../utils/generalQuestions');
const wikidataService = require('./wikidata-service');
const dbService = require('./question-data-service')
const dbService = require('./question-data-service');

/**
* Asynchronously generates a specified number of questions using data from the JSON file and stores them in the DB.
Expand Down Expand Up @@ -42,19 +42,55 @@ async function generateQuestions(n, language, questionCategory) {
const property = entity.properties[pos].property;
const categories = entity.properties[pos].category;
const filter = entity.properties[pos].filter;
const lang = language=="es"?0:1; //0 spanish, 1 english
const question = entity.properties[pos].template[lang].question;
// Now language is accessed directly:
const question = entity.properties[pos].template[language];

//let [entityName, searched_property] = await wikidataService.getRandomEntity(instance, property, filter);
let [entityName, searched_property] = await wikidataService.getRandomEntity(entity, pos, language);
let [entityName, searched_property] = [null, null]
let invalidEntity = false;
while ((!entityName || !searched_property) && !invalidEntity) {
try {
// If result for the entity is invalid, stops and logs the entity
let response = await wikidataService.getRandomEntity(entity, pos, language);
if (response && response.length === 2) {
[entityName, searched_property] = response;
} else {
console.error(`Error: getRandomEntity returned an invalid response for the entity: ${entity.name}`);
invalidEntity = true;
}
} catch (error) {
console.error("Error generating label for the answer: ", error.message);
console.error("Line:", error.stack.split("\n")[1]);
}
}
if (invalidEntity) {
continue;
}

if (searched_property !== null) {
//This way we can ask questions with different structures
const questionText = question.replace('x',entityName.charAt(0).toUpperCase() + entityName.slice(1)) +`?`;
// If that question is already in db, it goes on:
const questionAlreadyInDb = await dbService.getQuestion({"question": questionText});
if (!questionAlreadyInDb === undefined) {
console.log(`Question ${questionText} already in db, skipping`);
continue;
}

let correctAnswer = searched_property;

// options will contain 3 wrong answers plus the correct one
let options = await wikidataService.getProperties(property, language, filter);
let options;
try {
options = await wikidataService.getProperties(property, language, filter);

} catch (error) {
console.error(`Error generating options for ${entityName}: `, error.message);
console.error("Line:", error.stack.split("\n")[1]);
continue;
}
if (!options) {
continue;
}
options.push(correctAnswer);

//If properties are entities
Expand Down
7 changes: 1 addition & 6 deletions questions/services/question-data-service.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,25 +20,20 @@ module.exports = {
},


//TODO - Filter func not yet implemented
/**
* Returns a question from the database that could be filtered using a dictionary and removes it.
* @param {dict} filter - The dict containing the filter options for mongoose.
* @returns {Question} The question (it will be removed from DB)
*/
getQuestion : async function(filter = {}) {
try {
//const question = await Question.findOne(filter);
//return question;

//if there is filter
if (Object.keys(filter).length !== 0) {

const q = await Question.aggregate([
{ $match: filter },
{ $sample: { size: 1 } }
]);

return q[0];
} else {
//if not filter -> just random question
Expand Down
3 changes: 1 addition & 2 deletions questions/services/wikidata-service.js
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ async function getProperties(property, language, filt) {
query: consultaSparql,
format: 'json'
},
timeout: 15000 //means error
timeout: 30000 //means error
});
const endTime = new Date();
const elapsedTime = endTime - startTime;
Expand All @@ -102,7 +102,6 @@ async function getProperties(property, language, filt) {
}
return null;
} catch (error) {
console.error(error.stack);
console.error(`Error obtaining properties: ${error.message}`);
console.error("Line:", error.stack.split("\n")[1]);
return null;
Expand Down
Loading