From 5e7d483f94b9996201c69066a7628de478ed5de4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sa=C3=BAl=20Valdelvira?= Date: Sun, 9 Mar 2025 23:41:45 +0100 Subject: [PATCH] questions: Borrar ficheros antiguos --- .../__tests/routes/question-routes.test.js | 190 ------------- .../question-generation-service.test.js | 85 ------ .../__tests/services/question-service.test.js | 261 ------------------ .../__tests/services/wikidata-service.test.js | 172 ------------ .../__tests/utils/generalQuestions.test.js | 24 -- .../old/generate-questions-service.js | 127 --------- .../services/old/question-data-service.js | 144 ---------- questions/services/old/wikidata-service.js | 141 ---------- questions/services/question-data-model.js | 26 -- 9 files changed, 1170 deletions(-) delete mode 100644 questions/__tests/routes/question-routes.test.js delete mode 100644 questions/__tests/services/question-generation-service.test.js delete mode 100644 questions/__tests/services/question-service.test.js delete mode 100644 questions/__tests/services/wikidata-service.test.js delete mode 100644 questions/__tests/utils/generalQuestions.test.js delete mode 100644 questions/services/old/generate-questions-service.js delete mode 100644 questions/services/old/question-data-service.js delete mode 100644 questions/services/old/wikidata-service.js delete mode 100644 questions/services/question-data-model.js diff --git a/questions/__tests/routes/question-routes.test.js b/questions/__tests/routes/question-routes.test.js deleted file mode 100644 index 786be8e1..00000000 --- a/questions/__tests/routes/question-routes.test.js +++ /dev/null @@ -1,190 +0,0 @@ -import * as Question from '../../services/question-data-model.js'; -import { MongoMemoryServer } from 'mongodb-memory-server'; -import * as request from 'supertest'; -import * as mongoose from 'mongoose'; -import * as express from 'express'; -import * as bodyParser from 'body-parser'; - -let mongoServer; -let questionFunctions; -let questionRoutes; -let generateQuestionsService; - -//let mongoServer; -let app = express(); - -// const questionData1 = { -// question: "Which is the capital of Spain?", -// options: ["Madrid", "Barcelona", "Paris", "London"], -// correctAnswer: "Madrid", -// categories: ["Geography"], -// language: "en" -// }; - -// const questionData2 = { -// question: "Which is the capital of Spain?", -// options: ["Madrid", "Barcelona", "Paris", "London"], -// correctAnswer: "London", -// categories: ["Geography"], -// language: "en" -// }; - -//async function addingQuestion(questionData) { -// const newQuestion = new Question({ -// question: questionData.question, -// options: questionData.options, -// correctAnswer: questionData.correctAnswer, -// categories: questionData.categories, -// language: questionData.language -// }); -// //await newQuestion.save(); -// await questionFunctions.addQuestion(newQuestion); -//} - -//async function addingQuestions() { -// for(var i = 0; i < 24; i++) { -// await addingQuestion(questionData1); -// await addingQuestion(questionData2); -// } -//} - -beforeAll(async () => { - // mongoServer = await MongoMemoryServer.create(); - // const mongoURI = mongoServer.getUri(); - // process.env.DATABASE_URI = mongoURI; - // await mongoose.connect(mongoURI); - // questionFunctions = require('../../services/question-data-service'); - questionRoutes = require('../../routes/question-routes.js'); - // generateQuestionsService = require('../../services/generate-questions-service'); - // jest.mock('../../services/generate-questions-service'); - app.use(bodyParser.json()); - app.use('/questions', questionRoutes); -}); - -beforeEach(async () => { - //Load database with initial conditions - //await mongoose.connection.dropDatabase(); - // await Question.deleteMany({}); - // await addingQuestions(); -}); - - afterAll(async () => { - // Disconnect testing database after all tests - // await mongoose.disconnect(); - // await mongoServer.stop(); - }); - - -describe('Question routes', function() { - - describe("Get question (TEMPORAL TEST)", () => { - it("Should get a default dummy question", async () => { - const response = await request(app).get("/questions/random"); - expect(response.status).toBe(200) - expect(response.body.url).toBe("") - }) - }) - - // describe('Get a question from the database', function() { - // it('get question when 0 questions', async function() { - // await Question.deleteMany({}); - // await generateQuestionsService.generateQuestions.mockResolvedValue({"response":{"status":"200"}}); - // const response = await request(app).get('/questions/es'); - // await expect(response.status).toBe(200); - // await expect(response.body.question).toBe(undefined); - // }); - - // it('get question when less than 50 questions', async function() { - // await generateQuestionsService.generateQuestions.mockResolvedValue({"response":{"status":"200"}}); - // const response = await request(app).get('/questions/en'); - // await expect(response.status).toBe(200); - // await expect(response.body.question).toBe('Which is the capital of Spain?'); - // }); - - // it('get question when less than 100 questions', async function() { - // await addingQuestions(); - // await generateQuestionsService.generateQuestions.mockResolvedValue({"response":{"status":"200"}}); - // const response = await request(app).get('/questions/en'); - // await expect(response.status).toBe(200); - // await expect(response.body.question).toBe('Which is the capital of Spain?'); - // }); - - // it('get question when more than 100 questions', async function() { - // await addingQuestions(); - // await addingQuestions(); - // await generateQuestionsService.generateQuestions.mockResolvedValue({"response":{"status":"200"}}); - // const response = await request(app).get('/questions/en'); - // await expect(response.status).toBe(200); - // await expect(response.body.question).toBe('Which is the capital of Spain?'); - // }); - // }); - // describe('Get n questions from the database', function() { - // it('get question when less than 50 questions', async function() { - // await generateQuestionsService.generateQuestions.mockResolvedValue({"response":{"status":"200"}}); - // const response = await request(app).get('/questions/getQuestionsFromDb/3/en'); - // await expect(response.status).toBe(200); - // await expect(response.body.length).toBe(3); - // }); - - // it('get question when less than 100 questions', async function() { - // await addingQuestions(); - // await generateQuestionsService.generateQuestions.mockResolvedValue({"response":{"status":"200"}}); - // const response = await request(app).get('/questions/getQuestionsFromDb/3/en'); - // await expect(response.status).toBe(200); - // await expect(response.body.length).toBe(3); - // }); - - // it('get question when more than 100 questions', async function() { - // await addingQuestions(); - // await addingQuestions(); - // await generateQuestionsService.generateQuestions.mockResolvedValue({"response":{"status":"200"}}); - // const response = await request(app).get('/questions/getQuestionsFromDb/3/en'); - // await expect(response.status).toBe(200); - // await expect(response.body.length).toBe(3); - // }); - - // it('It should not get n questions from the database', async function() { - // const response = await request(app).get('/questions/getQuestionsFromDb/-1/en'); - // await expect(response.status).toBe(400); - // }); - // }); - // describe('Get n questions from the database filtered by category', function() { - - // it('get question when less than 50 questions', async function() { - // await generateQuestionsService.generateQuestions.mockResolvedValue({"response":{"status":"200"}}); - // const response = await request(app).get('/questions/getQuestionsFromDb/2/Geography/en'); - // await expect(response.status).toBe(200); - // await expect(response.body.length).toBe(2); - // await expect(response.body[0].categories[0]).toBe("Geography"); - // }); - // it('get question when less than 100 questions', async function() { - // await addingQuestions(); - // await generateQuestionsService.generateQuestions.mockResolvedValue({"response":{"status":"200"}}); - // const response = await request(app).get('/questions/getQuestionsFromDb/2/Geography/en'); - // await expect(response.status).toBe(200); - // await expect(response.body.length).toBe(2); - // await expect(response.body[0].categories[0]).toBe("Geography"); - // }); - - // it('get question when more than 100 questions', async function() { - // await addingQuestions(); - // await addingQuestions(); - // await generateQuestionsService.generateQuestions.mockResolvedValue({"response":{"status":"200"}}); - // const response = await request(app).get('/questions/getQuestionsFromDb/2/Geography/en'); - // await expect(response.status).toBe(200); - // await expect(response.body.length).toBe(2); - // await expect(response.body[0].categories[0]).toBe("Geography"); - // }); - - // it('It should not get n questions of certain category from the database', async function() { - // const response = await request(app).get('/questions/getQuestionsFromDb/-1/Geography/en'); - // await expect(response.status).toBe(400); - // }); - // }); - - // describe('MongoDB Connection', () => { - // it('should connect to the MongoDB server in memory', async () => { - // expect(mongoose.connection.readyState).toBe(1); // 1 means connected - // }); - // }); - }); diff --git a/questions/__tests/services/question-generation-service.test.js b/questions/__tests/services/question-generation-service.test.js deleted file mode 100644 index 4d68e3ba..00000000 --- a/questions/__tests/services/question-generation-service.test.js +++ /dev/null @@ -1,85 +0,0 @@ -import * as generator from '../../services/generate-questions-service.js'; -import * as dbService from '../../services/question-data-service.js'; -import * as wikidataService from '../../services/wikidata-service.js'; -import * as generalQuestions from '../../utils/generalQuestions.js'; - -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 -})); - -const entity = { - "name": "country", - "instance": "Q6256", - "properties": [ - { - "property": "P1082", - "template": { - "es": "Cuál es la población de x", - "en": "What is the population of x" - }, - "filter": ">1000000", - "category": ["Geography"] - } - ] -}; - - -beforeEach(() => { - // Reinicia el estado de los mocks antes de cada prueba - jest.clearAllMocks(); -}); -describe('Question generation', function() { - it('should generate questions', async () => { - // Configura los mocks de las dependencias según sea necesario para tus pruebas - const questions = [entity]; - generalQuestions.readFromFile.mockResolvedValue(questions); - - const entityName = 'Madrid'; - const searched_property = 'P18'; - wikidataService.getRandomEntity.mockResolvedValue([entityName, searched_property]); - - wikidataService.getProperties.mockResolvedValue(['Barcelona', 'Paris', 'London']); - wikidataService.convertUrlsToLabels.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"); - - // Verifica que la función haya realizado las operaciones esperadas - expect(dbService.addQuestion).toHaveBeenCalledTimes(1); - }); - - it('should cause an error', async () => { - // Configura los mocks de las dependencias según sea necesario para tus pruebas - const questions = entity; - generalQuestions.readFromFile.mockResolvedValue(questions); - - const entityName = 'Madrid'; - const searched_property = 'P18'; - wikidataService.getRandomEntity.mockResolvedValue([entityName, searched_property]); - - wikidataService.getProperties.mockResolvedValue(['Barcelona', 'Paris', 'London']); - wikidataService.convertUrlsToLabels.mockResolvedValue(['Barcelona', 'Paris', 'London']); - - generalQuestions.shuffleArray.mockResolvedValue(['Barcelona', 'Paris', 'London','Madrid']) - - dbService.addQuestion.mockResolvedValue(); - - console.error = jest.fn(); - // Llama a la función que deseas probar - await generator.generateQuestions(1,"en"); - - // Verifica que la función haya realizado las operaciones esperadas - expect(dbService.addQuestion).toHaveBeenCalledTimes(0); - - // Verifica si console.error fue llamado con el mensaje de error específico - expect(console.error).toHaveBeenCalledWith("Error generating questions: ","Cannot read properties of undefined (reading 'properties')"); - }); - -}); diff --git a/questions/__tests/services/question-service.test.js b/questions/__tests/services/question-service.test.js deleted file mode 100644 index c3c0da39..00000000 --- a/questions/__tests/services/question-service.test.js +++ /dev/null @@ -1,261 +0,0 @@ -import * as assert from 'assert'; -import * as mongoose from 'mongoose'; -import * as Question from '../../services/question-data-model.js'; -import { MongoMemoryServer } from 'mongodb-memory-server'; - -let mongoServer; -let questionFunctions; -let mongoURI; - -describe('Question Functions', function() { - beforeAll(async function() { - //Init a mongo memory server for the tests - mongoServer = await MongoMemoryServer.create(); - mongoURI = mongoServer.getUri(); - process.env.DATABASE_URI = mongoURI; - await mongoose.connect(mongoURI); - questionFunctions = require('../../services/question-data-service'); - }); - - afterEach(async function() { - // Clean database after each test - await Question.deleteMany({}); - }); - - afterAll(async function() { - // Disconnect at end - await mongoose.disconnect(); - await mongoServer.stop(); - }); - - describe('addQuestion', function() { - it('It should add a question to the database', async function() { - const questionData = { - question: "Which is the capital of Spain?", - options: ["Madrid", "Barcelona", "Paris", "London"], - correctAnswer: "Madrid", - categories: ["Geography"], - language: "en" - }; - await questionFunctions.addQuestion(questionData); - const questionInDB = await Question.findOne({ question: "Which is the capital of Spain?" }); - assert.strictEqual(questionInDB.question, "Which is the capital of Spain?"); - }); - - it('It should get an error message', async function() { - await mongoose.disconnect(); - const errorMsg = await questionFunctions.addQuestion({}); - assert.strictEqual(errorMsg, "Client must be connected before running operations"); - await mongoose.connect(mongoURI); - }); - }); - - describe('getQuestion', function() { - it('It should get a question from the database', async function() { - const questionData = { - question: "Which is the capital of Spain?", - options: ["Madrid", "Barcelona", "Paris", "London"], - correctAnswer: "Madrid", - categories: ["Geography"], - language: "en" - }; - const newQuestion = new Question(questionData); - await newQuestion.save(); - const questionInDB = await questionFunctions.getQuestion({ question: "Which is the capital of Spain?"}); - assert.strictEqual(questionInDB.question, "Which is the capital of Spain?"); - }); - - it('It should get an error message', async function() { - await mongoose.disconnect(); - const errorMsg = await questionFunctions.getQuestion(); - assert.strictEqual(errorMsg, "Client must be connected before running operations"); - await mongoose.connect(mongoURI); - }); - }); - - describe('getQuestionCount', function() { - it('It should count number of questions at the database', async function() { - const questionData = { - question: "Which is the capital of Spain?", - options: ["Madrid", "Barcelona", "Paris", "London"], - correctAnswer: "Madrid", - categories: ["Geography"], - language: "en" - }; - const newQuestion = new Question(questionData); - await newQuestion.save(); - - assert.strictEqual(await questionFunctions.getQuestionCount("en"), 1); - }); - - it('It should get an error message', async function() { - await mongoose.disconnect(); - const errorMsg = await questionFunctions.getQuestionCount("en"); - assert.strictEqual(errorMsg, "Client must be connected before running operations"); - await mongoose.connect(mongoURI); - }); - }); - - describe('getQuestionCountByCategory', function() { - it('It should count number of questions at the database filtered by category', async function() { - const questionData = { - question: "Which is the capital of Spain?", - options: ["Madrid", "Barcelona", "Paris", "London"], - correctAnswer: "Madrid", - categories: ["Geography"], - language: "en" - }; - const newQuestion = new Question(questionData); - await newQuestion.save(); - - assert.strictEqual(await questionFunctions.getQuestionCountByCategory("Geography","en"), 1); - assert.strictEqual(await questionFunctions.getQuestionCountByCategory("Political","en"), 0); - }); - - it('It should get an error message', async function() { - await mongoose.disconnect(); - const errorMsg = await questionFunctions.getQuestionCountByCategory(); - assert.strictEqual(errorMsg, "Client must be connected before running operations"); - await mongoose.connect(mongoURI); - }); - }); - - describe('deleteQuestionById', function() { - it('It should delete an added question from the database', async function() { - const questionData = { - question: "Which is the capital of Spain?", - options: ["Madrid", "Barcelona", "Paris", "London"], - correctAnswer: "Madrid", - categories: ["Geography"], - language: "en" - }; - const newQuestion = new Question(questionData); - const savedQuestion = await newQuestion.save(); - const savedQuestionId = savedQuestion._id; - - assert.strictEqual(await questionFunctions.getQuestionCount("en"), 1); - await questionFunctions.deleteQuestionById(savedQuestionId); - assert.strictEqual(await questionFunctions.getQuestionCount("en"), 0); - }); - - it('It should get an error message because of deleting with invalid id', async function() { - await mongoose.disconnect(); - const errorMsg = await questionFunctions.deleteQuestionById(""); - assert.strictEqual(errorMsg, 'Cast to ObjectId failed for value \"\" (type string) at path \"_id\" for model \"Question\"'); - await mongoose.connect(mongoURI); - }); - }); - - describe('getRandomQuestions', function() { - it('It should return two random questions (out of three in database)', async function() { - const questionData = { - question: "Which is the capital of Spain?", - options: ["Madrid", "Barcelona", "Paris", "London"], - correctAnswer: "Madrid", - categories: ["Geography"], - language: "en" - }; - - const questionData2 = { - question: "Which is the capital of France?", - options: ["Madrid", "Barcelona", "Paris", "London"], - correctAnswer: "Madrid", - categories: ["Geography"], - language: "en" - }; - - const questionData3 = { - question: "Which is the capital of UK?", - options: ["Madrid", "Barcelona", "Paris", "London"], - correctAnswer: "Madrid", - categories: ["Geography"], - language: "en" - }; - - await questionFunctions.addQuestion(questionData); - await questionFunctions.addQuestion(questionData2); - await questionFunctions.addQuestion(questionData3); - - const randomQuestions = await questionFunctions.getRandomQuestions(2,"en"); - - assert.strictEqual(randomQuestions.length, 2); - }); - - it('It should get two error messages', async function() { - const errorMsgSize = await questionFunctions.getRandomQuestions(40000); - assert.strictEqual(errorMsgSize, 'Required 40000 questions and there are 0'); - await mongoose.disconnect(); - const errorMsg = await questionFunctions.getRandomQuestions(1); - assert.strictEqual(errorMsg, "Client must be connected before running operations"); - await mongoose.connect(mongoURI); - }); - }); - - describe('getRandomQuestionsByCategory', function() { - it('It should return two random questions filtered by category', async function() { - const questionData = { - question: "Which is the capital of Spain?", - options: ["Madrid", "Barcelona", "Paris", "London"], - correctAnswer: "Madrid", - categories: ["Geography"], - language: "en" - }; - - const questionData2 = { - question: "Which is the capital of France?", - options: ["Madrid", "Barcelona", "Paris", "London"], - correctAnswer: "Madrid", - categories: ["Geography"], - language: "en" - }; - - const questionData3 = { - question: "Which is the capital of UK?", - options: ["Madrid", "Barcelona", "Paris", "London"], - correctAnswer: "Madrid", - categories: ["Geography"], - language: "en" - }; - - const questionData4 = { - question: "Which is the currency of Spain?", - options: ["Peseta", "Euro", "Duro", "Dollar"], - correctAnswer: "Euro", - categories: ["Political"], - language: "en" - }; - - await questionFunctions.addQuestion(questionData); - await questionFunctions.addQuestion(questionData2); - await questionFunctions.addQuestion(questionData3); - await questionFunctions.addQuestion(questionData4); - - const randomQuestions = await questionFunctions.getRandomQuestionsByCategory(2, "Geography","en"); - - assert.strictEqual(randomQuestions.length, 2); - - randomQuestions.forEach(question => { - assert.strictEqual(question.categories[0], "Geography"); - }); - - const randomQuestionPolitical = await questionFunctions.getRandomQuestionsByCategory(1, "Political","en"); - - assert.strictEqual(randomQuestionPolitical.length, 1); - - randomQuestionPolitical.forEach(question => { - assert.strictEqual(question.categories[0], "Political"); - }); - - }); - - it('It should get two error messages', async function() { - const errorMsgSize = await questionFunctions.getRandomQuestionsByCategory(40000, "Geography"); - assert.strictEqual(errorMsgSize, null); - await mongoose.disconnect(); - const errorMsg = await questionFunctions.getRandomQuestionsByCategory(1,"Geography","en"); - assert.strictEqual(errorMsg, "Client must be connected before running operations"); - await mongoose.connect(mongoURI); - }); - }); - -}); diff --git a/questions/__tests/services/wikidata-service.test.js b/questions/__tests/services/wikidata-service.test.js deleted file mode 100644 index 91513770..00000000 --- a/questions/__tests/services/wikidata-service.test.js +++ /dev/null @@ -1,172 +0,0 @@ -import * as axios from 'axios'; -import * as wikidataService from '../../services/wikidata-service'; -import * as MockAdapter from 'axios-mock-adapter'; - -const mockAxios = new MockAdapter(axios); - -const urlApiWikidata = 'https://query.wikidata.org/sparql'; - -const entity = { - "name": "country", - "instance": "Q6256", - "properties": [ - { - "property": "P1082", - "template": - [{ - "lang": "es", - "question": "Cuál es la población de x" - }, - { - "lang": "en", - "question": "What is the population of x" - }], - "filter": ">1000000", - "category": ["Geography"] - } - ] -}; - - -beforeEach(() => { - mockAxios.reset(); - - }); -describe('Get entity from wikidata', function() { - it('It should get an entity', async function() { - mockAxios.onGet(urlApiWikidata).reply(200, - { - results: { - bindings: [{ - entityLabel: { - value: 'Madrid' - }, - property: { - value: 'P18' - } - }] - } - } - ); - const response = await wikidataService.getRandomEntity(entity, 0, 1); - await expect(response[0]).toBe('Madrid'); - await expect(response[1]).toBe('P18'); - }); - it('It should fail when accessing wikidata', async function() { - mockAxios.onGet(urlApiWikidata).reply(400,"Error not found"); - - const response = await wikidataService.getRandomEntity(entity, 0, 1); - await expect(response).toBe(null); - }); - - it('It should fail when generating a question', async function() { - mockAxios.onGet(urlApiWikidata).reply(200, - { - results: { - bindings: [] - } - } - ); - const response = await wikidataService.getRandomEntity(entity, 0, 1); - await expect(response).toBe(null); - }); - -}); - -describe('Get properties from wikidata', function() { - it('It should get a list of properties', async function() { - mockAxios.onGet(urlApiWikidata).reply(200, - { - results: { - bindings: [{ - property: { - value: 'P31' - } - }] - } - } - ); - const response = await wikidataService.getProperties('P31', 1, ">1000000"); - await expect(response[0]).toBe('P31'); - await expect(response[1]).toBe('P31'); - await expect(response[2]).toBe('P31'); - }); - it('It should fail when accessing wikidata getting properties', async function() { - mockAxios.onGet(urlApiWikidata).reply(400,"Error not found"); - - const response = await wikidataService.getProperties('P18', 0); - await expect(response).toBe(null); - }); - - it('It should fail when getting properties', async function() { - mockAxios.onGet(urlApiWikidata).reply(200, - { - results: { - bindings: [] - } - } - ); - const response = await wikidataService.getProperties('P18', 0); - await expect(response).toBe(null); - }); - -}); - -describe('Get label from entities', function() { - it('Should get the entitys label in spanish', async function() { - const entity = [ - 'https://url/Q28' - ]; - mockAxios.onGet('https://www.wikidata.org/w/api.php?action=wbgetentities&format=json&ids=Q28').reply(200,{ - entities: { - Q28: { - labels: { - es: { - value: 'Madrid' - } - } - } - } - }); - const response = await wikidataService.convertUrlsToLabels(entity); - await expect(response[0]).toBe('Madrid'); - }); - - it('Should get the entitys label in english', async function() { - const entity = [ - 'https://url/Q28' - ]; - mockAxios.onGet('https://www.wikidata.org/w/api.php?action=wbgetentities&format=json&ids=Q28').reply(200,{ - entities: { - Q28: { - labels: { - en: { - value: 'Madrid' - } - } - } - } - }); - const response = await wikidataService.convertUrlsToLabels(entity); - await expect(response[0]).toBe('Madrid'); - }); - - it('Should not get any entitys label', async function() { - const entity = [ - 'https://url/Q28' - ]; - mockAxios.onGet('https://www.wikidata.org/w/api.php?action=wbgetentities&format=json&ids=Q28').reply(200,{ - entities: { - Q28: { - labels: { - fr: { - value: 'Madrid' - } - } - } - } - }); - const response = await wikidataService.convertUrlsToLabels(entity); - await expect(response[0]).toBe("no label (TEST)"); - }); -}); diff --git a/questions/__tests/utils/generalQuestions.test.js b/questions/__tests/utils/generalQuestions.test.js deleted file mode 100644 index e5f7c5e7..00000000 --- a/questions/__tests/utils/generalQuestions.test.js +++ /dev/null @@ -1,24 +0,0 @@ -import * as generalQuestions from '../../utils/generalQuestions' -import * as assert from 'assert'; - -describe('Shuffle array', function() { - it('It should shuffle an array', async function() { - const array = ['1','2','3','4']; - const response = generalQuestions.shuffleArray(array); - assert.notEqual( ['1','2','3','4'], response); - }); -}); - -describe('Read from file', function() { - it('It reads information from a file', async function() { - const response = await generalQuestions.readFromFile("../questions/utils/question.json"); - await expect(Array.isArray(response)).toBe(true); - }); - - it('It cannot read information from a file', async function() { - console.error = jest.fn(); - const response = await generalQuestions.readFromFile("../../questions/utils/question_error.json"); - await expect(response).toBe(null); - await expect(console.error).toHaveBeenCalledTimes(1); - }); -}); diff --git a/questions/services/old/generate-questions-service.js b/questions/services/old/generate-questions-service.js deleted file mode 100644 index 8573d290..00000000 --- a/questions/services/old/generate-questions-service.js +++ /dev/null @@ -1,127 +0,0 @@ -import * as utils from '../utils/generalQuestions.js'; -import * as wikidataService from './wikidata-service.js'; -import * as dbService from './question-data-service.js'; - -/** - * Asynchronously generates a specified number of questions using data from the JSON file and stores them in the DB. - * - * @param {number} n - The number of questions to generate. - * @returns {Promise} A Promise that resolves when all questions are generated. - */ -async function generateQuestions(n, language, questionCategory) { - try { - let json = await utils.readFromFile("../questions/utils/question.json"); - - //generate only questions from selected category - if (questionCategory) { - json = json.filter(obj => obj.properties.some(prop => prop.category.includes(questionCategory))); - } - - for (let i = 0; i < n; i++) { - //Gets random template - const randomIndex = Math.floor(Math.random() * json.length); - const entity = json[randomIndex]; - - // get data for selected entity - let pos = Math.floor(Math.random() * entity.properties.length); - - //use only property of that required category - if(questionCategory) { - const filteredProperties = []; - entity.properties.forEach(property => { - if (property.category.includes(questionCategory)) { - filteredProperties.push(property); - } - }); - - const randomPos = Math.floor(Math.random() * filteredProperties.length); - const propertyJson = filteredProperties[randomPos]; - pos = entity.properties.findIndex(prop => prop === propertyJson); - } - - const property = entity.properties[pos].property; - const categories = entity.properties[pos].category; - const filter = entity.properties[pos].filter; - // Now language is accessed directly: - const question = entity.properties[pos].template[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; - 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 - if(correctAnswer.startsWith("http:")) { - options = await wikidataService.convertUrlsToLabels(options); - //before shuffle correct answer is last one - correctAnswer = options[3]; - } - - // Shuffle options, we will not know where is the correct option - const shuffledOptions = utils.shuffleArray(options); - - // Create object with data for the question - const newQuestion = { - question: questionText, - options: shuffledOptions, - correctAnswer: correctAnswer, - categories: categories, - language: language - }; - - dbService.addQuestion(newQuestion); - - } - } - } catch (error) { - console.error("Error generating questions: ", error.message); - console.error("Line:", error.stack.split("\n")[1]); - } -} - -export { - generateQuestions -} diff --git a/questions/services/old/question-data-service.js b/questions/services/old/question-data-service.js deleted file mode 100644 index 9a10c048..00000000 --- a/questions/services/old/question-data-service.js +++ /dev/null @@ -1,144 +0,0 @@ -import * as mongoose from 'mongoose'; -import * as Question from './question-data-model.js'; -import { config } from "dotenv"; -config(); - -let uri = process.env.DATABASE_URI || 'mongodb://localhost:27017/questionDB'; -mongoose.connect(uri); - - // Add question to database - export async function addQuestion (questionData) { - try { - const newQuestion = new Question(questionData); - //console.log(newQuestion); - await newQuestion.save(); - console.log(`Question ${newQuestion._id} saved successfully in DB`); - } catch (error) { - console.error('Error adding the question: ', error.message); - return error.message; - } - } - - - /** - * 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) - */ - export async function getQuestion (filter = {}) { - try { - //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 - const q = await Question.aggregate([ - { $sample: { size: 1 } } - ]); - - return q[0]; - } - - } catch (error) { - console.error('Error obtaining the question', error.message); - return error.message; - } - } - - /** - * Deletes a question from the database. - * @param {id} str - The id of the document to be removed - */ - export async function deleteQuestionById (id) { - try { - await Question.findByIdAndDelete(id); - console.log(`Question ${id} deleted successfully`); - - } catch (error) { - console.error('Error deleting question:', error.message); - return error.message; - } - } - - /** - * Returns a the number of questions in the db. - * @returns {int} The question count - */ - export async function getQuestionCount (language) { - try { - // Obtain total number of questions in database - const totalQuestions = await Question.countDocuments({ language: language }); - return totalQuestions; - - } catch (error) { - console.error('Error obtaining the number of questions: ', error.message); - return error.message; - } - } - - /** - * Returns a the number of questions in the db. - * @returns {int} The question count - */ - export async function getQuestionCountByCategory (wantedCategory, wantedLanguage) { - try { - // Obtain total number of questions in database - const totalQuestions = await Question.countDocuments({ categories: wantedCategory, language: wantedLanguage }); - return totalQuestions; - - } catch (error) { - console.error('Error obtaining the number of questions for category ', wantedCategory,' and language', wantedLanguage,': ', error.message); - return error.message; - } - } - - - // Get random questions - async function getRandomQuestions(n, wantedLanguage) { - try { - // Obtain total number of questions in database - const totalQuestions = await Question.countDocuments({ language: wantedLanguage }); - - // Check if there are required number of questions - if (totalQuestions < n) { - console.log('Required ', n, ' questions and there are ', totalQuestions); - return 'Required ' + n + ' questions and there are ' + totalQuestions; - } - - return Question.aggregate([{ $match: { language: wantedLanguage } }, { $sample: { size: n } }]); - - } catch (error) { - console.error('Error obtaining random questions: ', error.message); - return error.message; - } - } - - // Obtaing random questions filtered by category - export async function getRandomQuestionsByCategory (n, wantedCategory, wantedLanguage) { - try { - console.log("getRandom: ",wantedLanguage); - // Obtain total number of questions with that category - const totalQuestions = await Question.countDocuments({ categories: wantedCategory, language: wantedLanguage }); - - // Check if there are required number of questions - if (totalQuestions < n) { - console.log('Required ', n, ' questions and there are ', totalQuestions); - return null; - } - - return Question.aggregate([ - { $match: { categories: wantedCategory, - language: wantedLanguage } }, - { $sample: { size: n } } - ]); - - } catch (error) { - console.error('Error obtaining random questions (with category): ', error.message); - return error.message; - } - } diff --git a/questions/services/old/wikidata-service.js b/questions/services/old/wikidata-service.js deleted file mode 100644 index 89611c15..00000000 --- a/questions/services/old/wikidata-service.js +++ /dev/null @@ -1,141 +0,0 @@ -import axios from 'axios'; - -async function getRandomEntity(entity, pos, language) { - - const property = entity.properties[pos].property; - const filt = entity.properties[pos].filter; - var filter = ''; - if(filt) { - filter = `FILTER(?property${filt})`; - } - //const language = entity.properties[pos].template[lang].lang; - const instance = entity.instance; - - const consultaSparql = ` - SELECT ?entity ?entityLabel ?property - WHERE { - ?entity wdt:P31 wd:${instance}; - wdt:${property} ?property. - ?entity rdfs:label ?entityLabel. - FILTER(LANG(?entityLabel) = "${language}") - ${filter} - } - `; - // it is better to use the FILTER rather than SERVICE - //SERVICE wikibase:label { bd:serviceParam wikibase:language "es". } - - const urlApiWikidata = 'https://query.wikidata.org/sparql'; - const headers = { - 'User-Agent': 'QuestionGeneration/1.0', - 'Accept': 'application/json', - }; - try { - response = await axios.get(urlApiWikidata, { - params: { - query: consultaSparql, - format: 'json' // Debe ser una cadena - }, - headers: headers, - }); - - - const data = await response.data - const entities = data.results.bindings; - - if (entities.length > 0) { - const randomEntity = entities[Math.floor(Math.random() * entities.length)]; - const entityName = randomEntity.entityLabel.value; - const property = randomEntity.property.value; - console.log("ENTITY, PROPERTY: ",entityName, property); - return [entityName, property]; - } else { - return null; - } - - } catch (error) { - console.error(`Error obtaining random entity: ${error.message}`); - return null; - } -} - - -async function getProperties(property, language, filt) { - var filter = ''; - if(filt) { - filter = `FILTER(?property${filt})`; - } - const consultaSparql = ` - SELECT DISTINCT ?property - WHERE { - ?entity wdt:${property} ?property. - ?entity rdfs:label ?entityLabel. - FILTER(LANG(?entityLabel) = "${language}") - ${filter} - } - LIMIT 400 - `; - const urlApiWikidata = 'https://query.wikidata.org/sparql'; - try { - const startTime = new Date(); - response = await axios.get(urlApiWikidata, { - params: { - query: consultaSparql, - format: 'json' - }, - timeout: 30000 //means error - }); - const endTime = new Date(); - const elapsedTime = endTime - startTime; - - console.log(`Waited ${elapsedTime} ms for the properties`); - - const data = await response.data; - const list = data.results.bindings; - - if(list.length > 0) { - const properties = new Array(3); - for(var i = 0; i < 3 ; i++) { - properties[i] = list[Math.floor(Math.random() * list.length)].property.value; - } - console.log("PROPERTIES: ",properties); - return properties; - } - return null; - } catch (error) { - console.error(`Error obtaining properties: ${error.message}`); - console.error("Line:", error.stack.split("\n")[1]); - return null; - } -} - -// return label of a entity -async function getEntityLabel(entityUrl) { - const apiUrl = `https://www.wikidata.org/w/api.php?action=wbgetentities&format=json&ids=${entityUrl}`; - const response = await axios.get(apiUrl); - const entity = response.data.entities[entityUrl]; - - if(entity.labels.en) { - return entity.labels.en.value; - } - if(entity.labels.es) { - return entity.labels.es.value; - } - - return "no label (TEST)"; - } - - // Change entities urls to labels - async function convertUrlsToLabels(options) { - const newOptions = options.map(url => { - const match = url.match(/\/Q(\d+)$/); - return match ? 'Q' + match[1] : null; - }); - const labels = await Promise.all(newOptions.map(getEntityLabel)); - return labels; - } - -export { - getRandomEntity, - getProperties, - convertUrlsToLabels -}; diff --git a/questions/services/question-data-model.js b/questions/services/question-data-model.js deleted file mode 100644 index 867b83db..00000000 --- a/questions/services/question-data-model.js +++ /dev/null @@ -1,26 +0,0 @@ -const mongoose = require('mongoose'); - -// Database schema -const questionSchema = new mongoose.Schema({ - question: String, - options: [String], - correctAnswer: String, - categories: [String], - // language: String, - wdUri: String, - image_url: String, - common_name: String, -}); - -//Auto generated id -// questionSchema.add({ -// id: { -// type: mongoose.Schema.Types.ObjectId, -// auto: true, -// unique: true, -// }, -// }); - -const Question = mongoose.model('Question', questionSchema); - -module.exports = { Question };