From 66f9ed83f2edf1ea78213442e65b2461742b117f Mon Sep 17 00:00:00 2001 From: Afif Al Mamun Date: Sun, 16 Apr 2023 01:32:30 +0600 Subject: [PATCH 1/7] Store user feedback This patch collects and stores user feedback on a collection upon feedback button clicks Fixes: 496 Signed-off-by: Afif Al Mamun --- TestResultSummaryService/Database.js | 8 ++ TestResultSummaryService/routes/index.js | 1 + .../routes/postIssueFeedback.js | 93 +++++++++++++++++++ .../src/Build/PossibleIssues.jsx | 86 ++++++++++++----- 4 files changed, 165 insertions(+), 23 deletions(-) create mode 100644 TestResultSummaryService/routes/postIssueFeedback.js diff --git a/TestResultSummaryService/Database.js b/TestResultSummaryService/Database.js index 977bbd15..f0a0adf6 100644 --- a/TestResultSummaryService/Database.js +++ b/TestResultSummaryService/Database.js @@ -335,6 +335,13 @@ class UserDB extends Database { } } +class FeedbackDB extends Database { + constructor() { + super(); + this.col = db.collection('feedback'); + } +} + module.exports = { TestResultsDB, OutputDB, @@ -343,4 +350,5 @@ module.exports = { AuditLogsDB, UserDB, ObjectID, + FeedbackDB, }; diff --git a/TestResultSummaryService/routes/index.js b/TestResultSummaryService/routes/index.js index 75f42d97..61318c30 100644 --- a/TestResultSummaryService/routes/index.js +++ b/TestResultSummaryService/routes/index.js @@ -64,5 +64,6 @@ app.post('/getParentSpecificData', wrap(require('./getParentSpecificData'))); app.post('/getSpecificData', wrap(require('./getSpecificData'))); app.post('/upsertBuildList', wrap(require('./upsertBuildList'))); app.post('/postTapFiles', wrap(require('./postTapFiles'))); +app.post('/postIssueFeedback', wrap(require('./postIssueFeedback'))); module.exports = app; diff --git a/TestResultSummaryService/routes/postIssueFeedback.js b/TestResultSummaryService/routes/postIssueFeedback.js new file mode 100644 index 00000000..c223f7d7 --- /dev/null +++ b/TestResultSummaryService/routes/postIssueFeedback.js @@ -0,0 +1,93 @@ +var fs = require('fs').promises; + +const { + FeedbackDB, + OutputDB, + ObjectID, + TestResultsDB, +} = require('../Database'); + +async function getTestResultData(testId) { + try { + const testResultsDB = new TestResultsDB(); + const result = await testResultsDB.getTestById(testId); + const data = result[0]; + return { + testOutputId: data.tests.testOutputId, + buildUrl: data.buildUrl, + buildNum: data.buildNum, + }; + } catch (error) { + throw error; + } +} + +function generateOutputFilename(testName, buildName, buildUrl, buildNum) { + const domain = new URL(buildUrl).hostname; + const fileName = `${testName}_${buildName}_${buildNum}_${domain}`; + + return fileName; +} + +async function getTestOutput(testId) { + try { + const outputDB = new OutputDB(); + const testResultData = await getTestResultData(testId); + const result = await outputDB + .getData({ _id: new ObjectID(testResultData.testOutputId) }) + .toArray(); + return { + ...testResultData, + testOutput: result[0].output, + }; + } catch (error) { + throw error; + } +} + +async function writeTestOutputToFile(testOutput, fileName) { + try { + const outputPath = `${__dirname}/../../MachineLearningPrototype/data/JenkinsDataWithFeedback/${fileName}.txt`; + await fs.writeFile(outputPath, testOutput); + } catch (error) { + throw error; + } +} + +module.exports = async (req, res) => { + try { + const db = new FeedbackDB(); + const { + repoName, + issueName, + issueCreator, + testId, + testName, + buildName, + issueNumber, + accuracy, + } = req.body; + const { testOutput, buildUrl, buildNum } = await getTestOutput(testId); + const outputFileName = generateOutputFilename( + testName, + buildName, + buildUrl, + buildNum + ); + await writeTestOutputToFile(testOutput, outputFileName); + await db.populateDB({ + repoName, + issueName, + issueCreator, + issueNumber, + testName, + testId, + testOutput: outputFileName, + accuracy, + }); + + res.send({ result: 'Feedback recorded' }); + } catch (error) { + res.status(500).send({ error: "Couldn't record feedback" }); + } +}; diff --git a/test-result-summary-client/src/Build/PossibleIssues.jsx b/test-result-summary-client/src/Build/PossibleIssues.jsx index 47cf36fe..823c93a2 100644 --- a/test-result-summary-client/src/Build/PossibleIssues.jsx +++ b/test-result-summary-client/src/Build/PossibleIssues.jsx @@ -1,5 +1,5 @@ import React, { Component } from 'react'; -import { Table, Button } from 'antd'; +import { Table, Button, notification, Space } from 'antd'; import TestBreadcrumb from './TestBreadcrumb'; import { getParams } from '../utils/query'; import { SmileOutlined, FrownOutlined } from '@ant-design/icons'; @@ -18,21 +18,50 @@ export default class PossibleIssues extends Component { await this.fetchIssues(); } - getUserFeedback = async ( + //issueID, testName, testOutput + + storeIssueFeedback = async ( repoName, buildName, issueName, + issueNumber, issueCreator, + testName, + testId, accuracy ) => { - const feedback = await fetchData( - `/api/getFeedbackUrl?repoName=${repoName}&buildName=${buildName}&issueName=${issueName}&issueCreator=${issueCreator}&accuracy=${accuracy}` - ); + try { + const postData = { + method: 'POST', + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json', + }, + body: JSON.stringify({ + repoName, + buildName, + issueName, + issueNumber, + issueCreator, + accuracy, + testName, + testId, + }), + }; - if (feedback.error) { - console.log(feedback.error); - } else { - console.log(feedback.output.result); + const response = await fetch(`/api/postIssueFeedback`, postData); + + if (response.status === 200) { + notification.success({ + message: 'Feedback collected', + }); + } else { + throw new Error('Write error'); + } + } catch (error) { + notification.error({ + message: 'Unable to collect feedback', + }); } }; @@ -127,17 +156,23 @@ export default class PossibleIssues extends Component { ); const issueState = relatedIssues.items[index].state; const issueFullName = relatedIssues.items[index].title; + const issueNumber = relatedIssues.items[index].number; const creatorName = relatedIssues.items[index].user.login; const userFeedback = ( <>