diff --git a/app/report/repositories/report_repository_test.go b/app/report/repositories/report_repository_test.go index e876324..79424eb 100644 --- a/app/report/repositories/report_repository_test.go +++ b/app/report/repositories/report_repository_test.go @@ -36,18 +36,23 @@ func TestReportrRepository_Save(t *testing.T) { // Create sample report for the test report := models.Report{ - UserID: 1, - AlertCount: 30, - AnalysisTime: 3600, - Predict: "Good", - Type: "Study", - CreatedAt: time.Now(), + UserID: 1, + AlertCount: 30, + AnalysisTime: 3600, + Type: "Study", + Predict: "Good", + Score: "90.000", + NormalRatio: "90.000", + NeckAngles: "angle", + Distances: "distance", + StatusFrequencies: "status", + CreatedAt: time.Now(), } // Set up expectations for the mock DB to return the sample report mock.ExpectBegin() mock.ExpectExec("INSERT INTO `reports`"). - WithArgs(report.UserID, report.AlertCount, report.AnalysisTime, report.Type, report.Predict, report.CreatedAt). + WithArgs(report.UserID, report.AlertCount, report.AnalysisTime, report.Type, report.Predict, report.Score, report.NormalRatio, report.NeckAngles, report.Distances, report.StatusFrequencies, report.CreatedAt). WillReturnResult(sqlmock.NewResult(1, 1)) mock.ExpectCommit() @@ -64,8 +69,14 @@ func TestReportrRepository_Save(t *testing.T) { assert.Equal(t, report.UserID, createdReport.UserID) assert.Equal(t, report.AlertCount, createdReport.AlertCount) assert.Equal(t, report.AnalysisTime, createdReport.AnalysisTime) - assert.Equal(t, report.Predict, createdReport.Predict) assert.Equal(t, report.Type, createdReport.Type) + assert.Equal(t, report.Predict, createdReport.Predict) + assert.Equal(t, report.Score, createdReport.Score) + assert.Equal(t, report.NormalRatio, createdReport.NormalRatio) + assert.Equal(t, report.NeckAngles, createdReport.NeckAngles) + assert.Equal(t, report.Distances, createdReport.Distances) + assert.Equal(t, report.StatusFrequencies, createdReport.StatusFrequencies) + assert.Equal(t, report.CreatedAt, createdReport.CreatedAt) } func TestReportRepository_Save_Error(t *testing.T) { @@ -92,18 +103,23 @@ func TestReportRepository_Save_Error(t *testing.T) { // Create sample report for the test report := models.Report{ - UserID: 1, - AlertCount: 30, - AnalysisTime: 3600, - Predict: "Good", - Type: "Study", - CreatedAt: time.Now(), + UserID: 1, + AlertCount: 30, + AnalysisTime: 3600, + Type: "Study", + Predict: "Good", + Score: "90.000", + NormalRatio: "90.000", + NeckAngles: "angle", + Distances: "distance", + StatusFrequencies: "status", + CreatedAt: time.Now(), } // Set up expectations for the mock DB to return the sample report mock.ExpectBegin() mock.ExpectExec("INSERT INTO `reports`"). - WithArgs(report.UserID, report.AlertCount, report.AnalysisTime, report.Type, report.Predict, report.CreatedAt). + WithArgs(report.UserID, report.AlertCount, report.AnalysisTime, report.Type, report.Predict, report.Score, report.NormalRatio, report.NeckAngles, report.Distances, report.StatusFrequencies, report.CreatedAt). WillReturnError(err) mock.ExpectRollback() @@ -141,18 +157,23 @@ func TestReportRepository_FindByUserID(t *testing.T) { // Create sample report for the test report := models.Report{ - UserID: 1, - AlertCount: 30, - AnalysisTime: 3600, - Predict: "Good", - Type: "Study", - CreatedAt: time.Now(), + UserID: 1, + AlertCount: 30, + AnalysisTime: 3600, + Type: "Study", + Predict: "Good", + Score: "90.000", + NormalRatio: "90.000", + NeckAngles: "angle", + Distances: "distance", + StatusFrequencies: "status", + CreatedAt: time.Now(), } // Set up expectations for the mock DB to return the sample report mock.ExpectBegin() mock.ExpectExec("INSERT INTO `reports`"). - WithArgs(report.UserID, report.AlertCount, report.AnalysisTime, report.Type, report.Predict, report.CreatedAt). + WithArgs(report.UserID, report.AlertCount, report.AnalysisTime, report.Type, report.Predict, report.Score, report.NormalRatio, report.NeckAngles, report.Distances, report.StatusFrequencies, report.CreatedAt). WillReturnResult(sqlmock.NewResult(1, 1)) mock.ExpectCommit() @@ -165,8 +186,8 @@ func TestReportRepository_FindByUserID(t *testing.T) { // Set up expectations for the mock DB to return the sample report mock.ExpectQuery("SELECT \\* FROM `reports` WHERE user_id = \\?"). WithArgs(report.UserID). - WillReturnRows(sqlmock.NewRows([]string{"id", "user_id", "alert_count", "analysis_time", "type", "predict", "created_at"}). - AddRow(savedReport.ID, savedReport.UserID, savedReport.AlertCount, savedReport.AnalysisTime, savedReport.Type, savedReport.Predict, savedReport.CreatedAt)) + WillReturnRows(sqlmock.NewRows([]string{"id", "user_id", "alert_count", "analysis_time", "type", "predict", "score", "normal_ratio", "neck_angles", "distances", "status_frequencies", "created_at"}). + AddRow(savedReport.ID, savedReport.UserID, savedReport.AlertCount, savedReport.AnalysisTime, savedReport.Type, savedReport.Predict, savedReport.Score, savedReport.NormalRatio, savedReport.NeckAngles, savedReport.Distances, savedReport.StatusFrequencies, savedReport.CreatedAt)) // Call the method under test reports, err := reportRepository.FindByUserID(report.UserID) @@ -181,8 +202,14 @@ func TestReportRepository_FindByUserID(t *testing.T) { assert.Equal(t, savedReport.UserID, reports[0].UserID) assert.Equal(t, savedReport.AlertCount, reports[0].AlertCount) assert.Equal(t, savedReport.AnalysisTime, reports[0].AnalysisTime) - assert.Equal(t, savedReport.Predict, reports[0].Predict) assert.Equal(t, savedReport.Type, reports[0].Type) + assert.Equal(t, savedReport.Predict, reports[0].Predict) + assert.Equal(t, savedReport.Score, reports[0].Score) + assert.Equal(t, savedReport.NormalRatio, reports[0].NormalRatio) + assert.Equal(t, savedReport.NeckAngles, reports[0].NeckAngles) + assert.Equal(t, savedReport.Distances, reports[0].Distances) + assert.Equal(t, savedReport.StatusFrequencies, reports[0].StatusFrequencies) + assert.Equal(t, savedReport.CreatedAt, reports[0].CreatedAt) } func TestReportRepository_FindByUserID_Error(t *testing.T) { @@ -245,18 +272,23 @@ func TestReportRepository_FindById(t *testing.T) { // Create sample report for the test report := models.Report{ - UserID: 1, - AlertCount: 30, - AnalysisTime: 3600, - Predict: "Good", - Type: "Study", - CreatedAt: time.Now(), + UserID: 1, + AlertCount: 30, + AnalysisTime: 3600, + Type: "Study", + Predict: "Good", + Score: "90.000", + NormalRatio: "90.000", + NeckAngles: "angle", + Distances: "distance", + StatusFrequencies: "status", + CreatedAt: time.Now(), } // Set up expectations for the mock DB to return the sample report mock.ExpectBegin() mock.ExpectExec("INSERT INTO `reports`"). - WithArgs(report.UserID, report.AlertCount, report.AnalysisTime, report.Type, report.Predict, report.CreatedAt). + WithArgs(report.UserID, report.AlertCount, report.AnalysisTime, report.Type, report.Predict, report.Score, report.NormalRatio, report.NeckAngles, report.Distances, report.StatusFrequencies, report.CreatedAt). WillReturnResult(sqlmock.NewResult(1, 1)) mock.ExpectCommit() @@ -269,8 +301,8 @@ func TestReportRepository_FindById(t *testing.T) { // Set up expectations for the mock DB to return the sample report mock.ExpectQuery("SELECT \\* FROM `reports` WHERE id = \\?"). WithArgs(savedReport.ID). - WillReturnRows(sqlmock.NewRows([]string{"id", "user_id", "alert_count", "analysis_time", "type", "predict", "created_at"}). - AddRow(savedReport.ID, savedReport.UserID, savedReport.AlertCount, savedReport.AnalysisTime, savedReport.Type, savedReport.Predict, savedReport.CreatedAt)) + WillReturnRows(sqlmock.NewRows([]string{"id", "user_id", "alert_count", "analysis_time", "type", "predict", "score", "normal_ratio", "neck_angles", "distances", "status_frequencies", "created_at"}). + AddRow(savedReport.ID, savedReport.UserID, savedReport.AlertCount, savedReport.AnalysisTime, savedReport.Type, savedReport.Predict, savedReport.Score, savedReport.NormalRatio, savedReport.NeckAngles, savedReport.Distances, savedReport.StatusFrequencies, savedReport.CreatedAt)) // Call the method under test report, err = reportRepository.FindById(savedReport.ID) @@ -285,8 +317,14 @@ func TestReportRepository_FindById(t *testing.T) { assert.Equal(t, savedReport.UserID, report.UserID) assert.Equal(t, savedReport.AlertCount, report.AlertCount) assert.Equal(t, savedReport.AnalysisTime, report.AnalysisTime) - assert.Equal(t, savedReport.Predict, report.Predict) assert.Equal(t, savedReport.Type, report.Type) + assert.Equal(t, savedReport.Predict, report.Predict) + assert.Equal(t, savedReport.Score, report.Score) + assert.Equal(t, savedReport.NormalRatio, report.NormalRatio) + assert.Equal(t, savedReport.NeckAngles, report.NeckAngles) + assert.Equal(t, savedReport.Distances, report.Distances) + assert.Equal(t, savedReport.StatusFrequencies, report.StatusFrequencies) + assert.Equal(t, savedReport.CreatedAt, report.CreatedAt) } func TestReportRepository_FindById_Error(t *testing.T) { @@ -348,18 +386,23 @@ func TestReportRepository_FindByYearAndMonth(t *testing.T) { // Create sample report for the test report := models.Report{ - UserID: 1, - AlertCount: 30, - AnalysisTime: 3600, - Predict: "Good", - Type: "Study", - CreatedAt: time.Now(), + UserID: 1, + AlertCount: 30, + AnalysisTime: 3600, + Type: "Study", + Predict: "Good", + Score: "90.000", + NormalRatio: "90.000", + NeckAngles: "angle", + Distances: "distance", + StatusFrequencies: "status", + CreatedAt: time.Now(), } // Set up expectations for the mock DB to return the sample report mock.ExpectBegin() mock.ExpectExec("INSERT INTO `reports`"). - WithArgs(report.UserID, report.AlertCount, report.AnalysisTime, report.Type, report.Predict, report.CreatedAt). + WithArgs(report.UserID, report.AlertCount, report.AnalysisTime, report.Type, report.Predict, report.Score, report.NormalRatio, report.NeckAngles, report.Distances, report.StatusFrequencies, report.CreatedAt). WillReturnResult(sqlmock.NewResult(1, 1)) mock.ExpectCommit() @@ -375,8 +418,8 @@ func TestReportRepository_FindByYearAndMonth(t *testing.T) { // Set up expectations for the mock DB to return the sample report mock.ExpectQuery("SELECT \\* FROM `reports` WHERE user_id = \\? AND DATE_FORMAT\\(created_at, '%Y%m'\\) = \\?"). WithArgs(savedReport.UserID, yearAndMonth). - WillReturnRows(sqlmock.NewRows([]string{"id", "user_id", "alert_count", "analysis_time", "type", "predict", "created_at"}). - AddRow(savedReport.ID, savedReport.UserID, savedReport.AlertCount, savedReport.AnalysisTime, savedReport.Type, savedReport.Predict, savedReport.CreatedAt)) + WillReturnRows(sqlmock.NewRows([]string{"id", "user_id", "alert_count", "analysis_time", "type", "predict", "score", "normal_ratio", "neck_angles", "distances", "status_frequencies", "created_at"}). + AddRow(savedReport.ID, savedReport.UserID, savedReport.AlertCount, savedReport.AnalysisTime, savedReport.Type, savedReport.Predict, savedReport.Score, savedReport.NormalRatio, savedReport.NeckAngles, savedReport.Distances, savedReport.StatusFrequencies, savedReport.CreatedAt)) // Call the method under test reports, err := reportRepository.FindByYearAndMonth(savedReport.UserID, yearAndMonth) @@ -391,8 +434,14 @@ func TestReportRepository_FindByYearAndMonth(t *testing.T) { assert.Equal(t, savedReport.UserID, reports[0].UserID) assert.Equal(t, savedReport.AlertCount, reports[0].AlertCount) assert.Equal(t, savedReport.AnalysisTime, reports[0].AnalysisTime) - assert.Equal(t, savedReport.Predict, reports[0].Predict) assert.Equal(t, savedReport.Type, reports[0].Type) + assert.Equal(t, savedReport.Predict, reports[0].Predict) + assert.Equal(t, savedReport.Score, reports[0].Score) + assert.Equal(t, savedReport.NormalRatio, reports[0].NormalRatio) + assert.Equal(t, savedReport.NeckAngles, reports[0].NeckAngles) + assert.Equal(t, savedReport.Distances, reports[0].Distances) + assert.Equal(t, savedReport.StatusFrequencies, reports[0].StatusFrequencies) + assert.Equal(t, savedReport.CreatedAt, reports[0].CreatedAt) } func TestReportRepository_FindByYearAndMonth_Error(t *testing.T) { @@ -457,18 +506,23 @@ func TestReportRepository_FindAll(t *testing.T) { // Create sample report for the test report := models.Report{ - UserID: 1, - AlertCount: 30, - AnalysisTime: 3600, - Predict: "Good", - Type: "Study", - CreatedAt: time.Now(), + UserID: 1, + AlertCount: 30, + AnalysisTime: 3600, + Type: "Study", + Predict: "Good", + Score: "90.000", + NormalRatio: "90.000", + NeckAngles: "angle", + Distances: "distance", + StatusFrequencies: "status", + CreatedAt: time.Now(), } // Set up expectations for the mock DB to return the sample report mock.ExpectBegin() mock.ExpectExec("INSERT INTO `reports`"). - WithArgs(report.UserID, report.AlertCount, report.AnalysisTime, report.Type, report.Predict, report.CreatedAt). + WithArgs(report.UserID, report.AlertCount, report.AnalysisTime, report.Type, report.Predict, report.Score, report.NormalRatio, report.NeckAngles, report.Distances, report.StatusFrequencies, report.CreatedAt). WillReturnResult(sqlmock.NewResult(1, 1)) mock.ExpectCommit() @@ -480,8 +534,8 @@ func TestReportRepository_FindAll(t *testing.T) { // Set up expectations for the mock DB to return the sample report mock.ExpectQuery("SELECT \\* FROM `reports`"). - WillReturnRows(sqlmock.NewRows([]string{"id", "user_id", "alert_count", "analysis_time", "type", "predict", "created_at"}). - AddRow(savedReport.ID, savedReport.UserID, savedReport.AlertCount, savedReport.AnalysisTime, savedReport.Type, savedReport.Predict, savedReport.CreatedAt)) + WillReturnRows(sqlmock.NewRows([]string{"id", "user_id", "alert_count", "analysis_time", "type", "predict", "score", "normal_ratio", "neck_angles", "distances", "status_frequencies", "created_at"}). + AddRow(savedReport.ID, savedReport.UserID, savedReport.AlertCount, savedReport.AnalysisTime, savedReport.Type, savedReport.Predict, savedReport.Score, savedReport.NormalRatio, savedReport.NeckAngles, savedReport.Distances, savedReport.StatusFrequencies, savedReport.CreatedAt)) // Call the method under test reports, err := reportRepository.FindAll() @@ -496,8 +550,14 @@ func TestReportRepository_FindAll(t *testing.T) { assert.Equal(t, savedReport.UserID, reports[0].UserID) assert.Equal(t, savedReport.AlertCount, reports[0].AlertCount) assert.Equal(t, savedReport.AnalysisTime, reports[0].AnalysisTime) - assert.Equal(t, savedReport.Predict, reports[0].Predict) assert.Equal(t, savedReport.Type, reports[0].Type) + assert.Equal(t, savedReport.Predict, reports[0].Predict) + assert.Equal(t, savedReport.Score, reports[0].Score) + assert.Equal(t, savedReport.NormalRatio, reports[0].NormalRatio) + assert.Equal(t, savedReport.NeckAngles, reports[0].NeckAngles) + assert.Equal(t, savedReport.Distances, reports[0].Distances) + assert.Equal(t, savedReport.StatusFrequencies, reports[0].StatusFrequencies) + assert.Equal(t, savedReport.CreatedAt, reports[0].CreatedAt) } func TestReportRepository_FindAll_Error(t *testing.T) { diff --git a/app/report/services/report_service.go b/app/report/services/report_service.go index 9538836..b1b0605 100644 --- a/app/report/services/report_service.go +++ b/app/report/services/report_service.go @@ -1,6 +1,7 @@ package services import ( + "encoding/json" "fmt" "gdsc/baro/app/report/models" "gdsc/baro/app/report/repositories" @@ -8,15 +9,14 @@ import ( usermodel "gdsc/baro/app/user/models" "gdsc/baro/global/fcm" "gdsc/baro/global/utils" + "io" "os" - "strings" "time" "net/http" "net/url" "github.com/gin-gonic/gin" - "golang.org/x/net/html" ) type ReportServiceInterface interface { @@ -66,12 +66,20 @@ func Predict(service ReportService, url string, user usermodel.User, input types return err } + result, scores, nomalRatio, statusFrequencies, distances, landmarksInfo := ParseAnalysis(&response) + score := CalculateScores(result, scores) + report := models.Report{ - UserID: user.ID, - AlertCount: input.AlertCount, - AnalysisTime: input.AnalysisTime, - Type: input.Type, - Predict: response, + UserID: user.ID, + AlertCount: input.AlertCount, + AnalysisTime: input.AnalysisTime, + Type: input.Type, + Predict: fmt.Sprintf("%v", result), + Score: score, + NormalRatio: nomalRatio, + StatusFrequencies: statusFrequencies, + Distances: distances, + NeckAngles: landmarksInfo, } savedReport, _ := service.ReportRepository.Save(&report) @@ -86,26 +94,118 @@ func Predict(service ReportService, url string, user usermodel.User, input types return nil } -func HandleRequest(url string) (string, error) { - req, err := http.NewRequest("POST", url, nil) +func HandleRequest(url string) (types.ResponseAnalysis, error) { + req, err := http.NewRequest("GET", url, nil) if err != nil { - return "", err + return types.ResponseAnalysis{}, err } client := &http.Client{} + response, err := client.Do(req) if err != nil { - return "", err + return types.ResponseAnalysis{}, err } defer response.Body.Close() - doc, err := html.Parse(response.Body) + body, err := io.ReadAll(response.Body) + if err != nil { + return types.ResponseAnalysis{}, err + } + + var data types.ResponseAnalysis + err = json.Unmarshal([]byte(body), &data) if err != nil { - return "", err + fmt.Println("응답 파싱 에러:", err) + return types.ResponseAnalysis{}, err } - return ParseHTML(doc), nil + return data, nil +} + +func ParseAnalysis(response *types.ResponseAnalysis) ([]int, []float64, string, string, string, string) { + // 결과 및 신뢰도 + result := response.Result + scores := response.Scores + + // 정상 비율 + nomalRatio := response.NormalRatio + + // 빈도수 + statusFrequencies := []int{ + response.StatusFrequencies["Fine"], + response.StatusFrequencies["Danger"], + response.StatusFrequencies["Serious"], + response.StatusFrequencies["Very Serious"], + } + + // 없는 필드는 0으로 초기화 + for i := range statusFrequencies { + if statusFrequencies[i] == 0 { + statusFrequencies[i] = 0 + } + } + + // 길이 및 각도 + var distances []float64 + var angles []float64 + for i := range response.LandmarksInfo { + // response.LandmarksInfo[i][2] = 길이 + // response.LandmarksInfo[i][3] = 각도 + distances = append(distances, response.LandmarksInfo[i][2].(float64)) + angles = append(angles, response.LandmarksInfo[i][3].(float64)) + } + + return result, scores, fmt.Sprintf("%.3f", nomalRatio), fmt.Sprintf("%v", statusFrequencies), fmt.Sprintf("%.3f", distances), fmt.Sprintf("%.3f", angles) +} + +func CalculateScores(result []int, scores []float64) string { + normalCases := make([]float64, 0, len(result)) + abnormalCases := make([]float64, 0, len(result)) + + for i, r := range result { + if r == 1 { + normalCases = append(normalCases, scores[i]) + } else { + abnormalCases = append(abnormalCases, scores[i]) + } + } + + totalCases := len(normalCases) + len(abnormalCases) + caseScore := 100.0 / float64(totalCases) + + var totalScore float64 + + for _, score := range normalCases { + switch { + case score >= 90: + totalScore += 1.0 * caseScore + case score >= 80: + totalScore += 0.98 * caseScore + case score >= 70: + totalScore += 0.95 * caseScore + default: + totalScore += 0.9 * caseScore + } + } + + for _, score := range abnormalCases { + switch { + case score >= 90: + totalScore += 0.15 * caseScore + case score >= 80: + totalScore += 0.2 * caseScore + case score >= 70: + totalScore += 0.25 * caseScore + case score >= 60: + totalScore += 0.27 * caseScore + default: + totalScore += 0.3 * caseScore + } + } + + return fmt.Sprintf("%.2f", totalScore) } func GenerateMessage(date string) (string, string, error) { @@ -135,19 +235,6 @@ func GenerateMessage(date string) (string, string, error) { return title, body, nil } -func ParseHTML(n *html.Node) string { - if n.Type == html.ElementNode && n.Data == "p" { - return n.FirstChild.Data - } - for c := n.FirstChild; c != nil; c = c.NextSibling { - result := ParseHTML(c) - if strings.TrimSpace(result) != "" { - return result - } - } - return "" -} - func (service *ReportService) FindReportByCurrentUser(c *gin.Context) ([]types.ResponseReport, error) { user, err := service.UserUtil.FindCurrentUser(c) if err != nil { @@ -162,13 +249,18 @@ func (service *ReportService) FindReportByCurrentUser(c *gin.Context) ([]types.R var responseReports []types.ResponseReport for _, report := range reports { responseReport := types.ResponseReport{ - ID: report.ID, - UserID: report.UserID, - AlertCount: report.AlertCount, - AnalysisTime: report.AnalysisTime, - Predict: report.Predict, - Type: report.Type, - CreatedAt: report.CreatedAt, + ID: report.ID, + UserID: report.UserID, + AlertCount: report.AlertCount, + AnalysisTime: report.AnalysisTime, + Type: report.Type, + Predict: report.Predict, + Score: report.Score, + NormalRatio: report.NormalRatio, + NeckAngles: report.NeckAngles, + Distances: report.Distances, + StatusFrequencies: report.StatusFrequencies, + CreatedAt: report.CreatedAt, } responseReports = append(responseReports, responseReport) } @@ -183,13 +275,18 @@ func (service *ReportService) FindById(c *gin.Context, id uint) (types.ResponseR } responseReport := types.ResponseReport{ - ID: report.ID, - UserID: report.UserID, - AlertCount: report.AlertCount, - AnalysisTime: report.AnalysisTime, - Predict: report.Predict, - Type: report.Type, - CreatedAt: report.CreatedAt, + ID: report.ID, + UserID: report.UserID, + AlertCount: report.AlertCount, + AnalysisTime: report.AnalysisTime, + Type: report.Type, + Predict: report.Predict, + Score: report.Score, + NormalRatio: report.NormalRatio, + NeckAngles: report.NeckAngles, + Distances: report.Distances, + StatusFrequencies: report.StatusFrequencies, + CreatedAt: report.CreatedAt, } return responseReport, nil @@ -221,13 +318,18 @@ func (service *ReportService) FindAll() ([]types.ResponseReport, error) { var responseReports []types.ResponseReport for _, report := range reports { responseReport := types.ResponseReport{ - ID: report.ID, - UserID: report.UserID, - AlertCount: report.AlertCount, - AnalysisTime: report.AnalysisTime, - Predict: report.Predict, - Type: report.Type, - CreatedAt: report.CreatedAt, + ID: report.ID, + UserID: report.UserID, + AlertCount: report.AlertCount, + AnalysisTime: report.AnalysisTime, + Type: report.Type, + Predict: report.Predict, + Score: report.Score, + NormalRatio: report.NormalRatio, + NeckAngles: report.NeckAngles, + Distances: report.Distances, + StatusFrequencies: report.StatusFrequencies, + CreatedAt: report.CreatedAt, } responseReports = append(responseReports, responseReport) } diff --git a/app/report/services/report_service_test.go b/app/report/services/report_service_test.go index 8fb6364..d24f749 100644 --- a/app/report/services/report_service_test.go +++ b/app/report/services/report_service_test.go @@ -2,19 +2,18 @@ package services_test import ( "errors" + "fmt" "gdsc/baro/app/report/models" "gdsc/baro/app/report/services" "gdsc/baro/app/report/types" usermodel "gdsc/baro/app/user/models" "os" - "strings" "testing" "time" "github.com/gin-gonic/gin" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" - "golang.org/x/net/html" ) type MockReportRepository struct { @@ -158,6 +157,119 @@ func TestHandleRequest(t *testing.T) { assert.True(t, true) } +func TestParseAnalysis(t *testing.T) { + // response *types.ResponseAnalysis + response := types.ResponseAnalysis{ + Result: []int{0, 1, 1, 1, 0, 1}, + HunchedRatio: 10.0, + NormalRatio: 90.0, + Scores: []float64{99.9, 92.9, 82.3, 92.4, 69.5}, + LandmarksInfo: [][]interface{}{ + {[]float64{0.1, 0.2}, []float64{0.3, 0.4}, 1.0, 45.0}, + {[]float64{0.5, 0.6}, []float64{0.7, 0.8}, 2.0, 60.0}, + }, + StatusFrequencies: map[string]int{"Very Serious": 6}, + } + + // Execute method under test + result, scores, nomalRatio, statusFrequencies, distances, landmarksInfo := services.ParseAnalysis(&response) + + // Assert result + assert.Equal(t, response.Result, result) + assert.Equal(t, response.Scores, scores) + assert.Equal(t, fmt.Sprintf("%.3f", response.NormalRatio), nomalRatio) + assert.Equal(t, fmt.Sprintf("%.3f", []float64{1.0, 2.0}), distances) + assert.Equal(t, fmt.Sprintf("%.3f", []float64{45.0, 60.0}), landmarksInfo) + assert.Equal(t, fmt.Sprintf("%v", []string{"0", "0", "0", "6"}), statusFrequencies) +} + +func TestParseAnalysis_NoStatusFrequencies(t *testing.T) { + // response *types.ResponseAnalysis + response := types.ResponseAnalysis{ + Result: []int{0, 1, 1, 1, 0, 1}, + HunchedRatio: 10.0, + NormalRatio: 90.0, + Scores: []float64{99.9, 92.9, 82.3, 92.4, 69.5}, + LandmarksInfo: [][]interface{}{ + {[]float64{0.1, 0.2}, []float64{0.3, 0.4}, 1.0, 45.0}, + {[]float64{0.5, 0.6}, []float64{0.7, 0.8}, 2.0, 60.0}, + }, + } + + // Execute method under test + result, scores, nomalRatio, statusFrequencies, distances, landmarksInfo := services.ParseAnalysis(&response) + + // Assert result + assert.Equal(t, response.Result, result) + assert.Equal(t, response.Scores, scores) + assert.Equal(t, fmt.Sprintf("%.3f", response.NormalRatio), nomalRatio) + assert.Equal(t, fmt.Sprintf("%.3f", []float64{1.0, 2.0}), distances) + assert.Equal(t, fmt.Sprintf("%.3f", []float64{45.0, 60.0}), landmarksInfo) + assert.Equal(t, fmt.Sprintf("%v", []string{"0", "0", "0", "0"}), statusFrequencies) +} + +func TestParseAnalysis_FullStatusFrequencies(t *testing.T) { + // response *types.ResponseAnalysis + response := types.ResponseAnalysis{ + Result: []int{0, 1, 1, 1, 0, 1}, + HunchedRatio: 10.0, + NormalRatio: 90.0, + Scores: []float64{99.9, 92.9, 82.3, 92.4, 69.5}, + LandmarksInfo: [][]interface{}{ + {[]float64{0.1, 0.2}, []float64{0.3, 0.4}, 1.0, 45.0}, + {[]float64{0.5, 0.6}, []float64{0.7, 0.8}, 2.0, 60.0}, + }, + StatusFrequencies: map[string]int{"Fine": 1, "Danger": 2, "Serious": 1, "Very Serious": 2}, + } + + // Execute method under test + result, scores, nomalRatio, statusFrequencies, distances, landmarksInfo := services.ParseAnalysis(&response) + + // Assert result + assert.Equal(t, response.Result, result) + assert.Equal(t, response.Scores, scores) + assert.Equal(t, fmt.Sprintf("%.3f", response.NormalRatio), nomalRatio) + assert.Equal(t, fmt.Sprintf("%.3f", []float64{1.0, 2.0}), distances) + assert.Equal(t, fmt.Sprintf("%.3f", []float64{45.0, 60.0}), landmarksInfo) + assert.Equal(t, fmt.Sprintf("%v", []string{"1", "2", "1", "2"}), statusFrequencies) +} + +func TestCalculateScores_AllBad(t *testing.T) { + // Set up test data + testResult := []int{0, 0, 0, 0, 0, 0} + testScores := []float64{99.9, 92.9, 92.3, 92.4, 99.5, 92.0} + + // Execute method under test + result := services.CalculateScores(testResult, testScores) + + // Assert result + assert.Equal(t, "15.00", result) +} + +func TestCalculateScores_HalfGood(t *testing.T) { + // Set up test data + testResult := []int{0, 0, 0, 1, 1, 1} + testScores := []float64{99.9, 92.9, 92.3, 92.4, 99.5, 92.0} + + // Execute method under test + result := services.CalculateScores(testResult, testScores) + + // Assert result + assert.Equal(t, "57.50", result) +} + +func TestCalculateScores_AllGood(t *testing.T) { + // Set up test data + testResult := []int{1, 1, 1, 1, 1, 1} + testScores := []float64{99.9, 92.9, 92.3, 92.4, 99.5, 92.0} + + // Execute method under test + result := services.CalculateScores(testResult, testScores) + + // Assert result + assert.Equal(t, "100.00", result) +} + func TestGenerateMessage(t *testing.T) { // Set up test data testTimes := []string{ @@ -190,32 +302,6 @@ func TestGenerateMessage_InvaildData(t *testing.T) { assert.Equal(t, "", body) } -func TestParseHTML(t *testing.T) { - // Set up test data - testHTML := "

Test

" - doc, err := html.Parse(strings.NewReader(testHTML)) - assert.Nil(t, err) - - // Execute method under test - result := services.ParseHTML(doc) - - // Assert result - assert.Equal(t, "Test", result) -} - -func TestParseHTML_NoData(t *testing.T) { - // Set up test data - testHTML := "" - doc, err := html.Parse(strings.NewReader(testHTML)) - assert.Nil(t, err) - - // Execute method under test - result := services.ParseHTML(doc) - - // Assert result - assert.Equal(t, "", result) -} - func TestFindReportByCurrentUser(t *testing.T) { // Mock UserRepository, UserUtil mockReportRepository := new(MockReportRepository) @@ -237,20 +323,30 @@ func TestFindReportByCurrentUser(t *testing.T) { // Set up sample reports for the test reports := []models.Report{ { - ID: 1, - UserID: 1, - AlertCount: 10, - AnalysisTime: 1800, - Predict: "Good", - Type: "Study", + ID: 1, + UserID: 1, + AlertCount: 10, + AnalysisTime: 1800, + Type: "Study", + Predict: "Good", + Score: "90.000", + NormalRatio: "90.000", + NeckAngles: "angle", + Distances: "distance", + StatusFrequencies: "status", }, { - ID: 2, - UserID: 1, - AlertCount: 30, - AnalysisTime: 3600, - Predict: "Good", - Type: "Study", + ID: 2, + UserID: 1, + AlertCount: 10, + AnalysisTime: 1800, + Type: "Study", + Predict: "Good", + Score: "90.000", + NormalRatio: "90.000", + NeckAngles: "angle", + Distances: "distance", + StatusFrequencies: "status", }, } @@ -276,8 +372,13 @@ func TestFindReportByCurrentUser(t *testing.T) { assert.Equal(t, report.UserID, responseReports[i].UserID) assert.Equal(t, report.AlertCount, responseReports[i].AlertCount) assert.Equal(t, report.AnalysisTime, responseReports[i].AnalysisTime) - assert.Equal(t, report.Predict, responseReports[i].Predict) assert.Equal(t, report.Type, responseReports[i].Type) + assert.Equal(t, report.Predict, responseReports[i].Predict) + assert.Equal(t, report.Score, responseReports[i].Score) + assert.Equal(t, report.NormalRatio, responseReports[i].NormalRatio) + assert.Equal(t, report.NeckAngles, responseReports[i].NeckAngles) + assert.Equal(t, report.Distances, responseReports[i].Distances) + assert.Equal(t, report.StatusFrequencies, responseReports[i].StatusFrequencies) } } @@ -352,12 +453,17 @@ func TestFindById(t *testing.T) { // Set up sample report for the test report := models.Report{ - ID: 1, - UserID: 1, - AlertCount: 10, - AnalysisTime: 1800, - Predict: "Good", - Type: "Study", + ID: 1, + UserID: 1, + AlertCount: 10, + AnalysisTime: 1800, + Type: "Study", + Predict: "Good", + Score: "90.000", + NormalRatio: "90.000", + NeckAngles: "angle", + Distances: "distance", + StatusFrequencies: "status", } // Set up expectations for the mock repository @@ -379,8 +485,13 @@ func TestFindById(t *testing.T) { assert.Equal(t, report.UserID, responseReport.UserID) assert.Equal(t, report.AlertCount, responseReport.AlertCount) assert.Equal(t, report.AnalysisTime, responseReport.AnalysisTime) - assert.Equal(t, report.Predict, responseReport.Predict) assert.Equal(t, report.Type, responseReport.Type) + assert.Equal(t, report.Predict, responseReport.Predict) + assert.Equal(t, report.Score, responseReport.Score) + assert.Equal(t, report.NormalRatio, responseReport.NormalRatio) + assert.Equal(t, report.NeckAngles, responseReport.NeckAngles) + assert.Equal(t, report.Distances, responseReport.Distances) + assert.Equal(t, report.StatusFrequencies, responseReport.StatusFrequencies) } func TestFindById_NoReport(t *testing.T) { @@ -430,22 +541,32 @@ func TestFindReportSummaryByMonth(t *testing.T) { // Set up sample reports for the test reports := []models.Report{ { - ID: 1, - UserID: 1, - AlertCount: 10, - AnalysisTime: 1800, - Predict: "Good", - Type: "Study", - CreatedAt: time.Now(), + ID: 1, + UserID: 1, + AlertCount: 10, + AnalysisTime: 1800, + Type: "Study", + Predict: "Good", + Score: "90.000", + NormalRatio: "90.000", + NeckAngles: "angle", + Distances: "distance", + StatusFrequencies: "status", + CreatedAt: time.Now(), }, { - ID: 2, - UserID: 1, - AlertCount: 30, - AnalysisTime: 3600, - Predict: "Good", - Type: "Study", - CreatedAt: time.Now(), + ID: 2, + UserID: 1, + AlertCount: 10, + AnalysisTime: 1800, + Type: "Study", + Predict: "Good", + Score: "90.000", + NormalRatio: "90.000", + NeckAngles: "angle", + Distances: "distance", + StatusFrequencies: "status", + CreatedAt: time.Now(), }, } @@ -550,22 +671,32 @@ func TestFindAll(t *testing.T) { // Set up sample reports for the test reports := []models.Report{ { - ID: 1, - UserID: 1, - AlertCount: 10, - AnalysisTime: 1800, - Predict: "Good", - Type: "Study", - CreatedAt: time.Now(), + ID: 1, + UserID: 1, + AlertCount: 10, + AnalysisTime: 1800, + Type: "Study", + Predict: "Good", + Score: "90.000", + NormalRatio: "90.000", + NeckAngles: "angle", + Distances: "distance", + StatusFrequencies: "status", + CreatedAt: time.Now(), }, { - ID: 2, - UserID: 1, - AlertCount: 30, - AnalysisTime: 3600, - Predict: "Good", - Type: "Study", - CreatedAt: time.Now(), + ID: 2, + UserID: 1, + AlertCount: 30, + AnalysisTime: 3600, + Type: "Study", + Predict: "Good", + Score: "90.000", + NormalRatio: "90.000", + NeckAngles: "angle", + Distances: "distance", + StatusFrequencies: "status", + CreatedAt: time.Now(), }, } diff --git a/app/report/types/response_types.go b/app/report/types/response_types.go index 552e1cb..110367d 100644 --- a/app/report/types/response_types.go +++ b/app/report/types/response_types.go @@ -7,12 +7,26 @@ type ResponseReportSummary struct { CreatedAt time.Time `json:"created_at"` } +type ResponseAnalysis struct { + Result []int `json:"result"` + HunchedRatio float64 `json:"hunched_ratio"` + NormalRatio float64 `json:"normal_ratio"` + Scores []float64 `json:"scores"` + LandmarksInfo [][]interface{} `json:"landmarks_info"` + StatusFrequencies map[string]int `json:"status_frequencies"` +} + type ResponseReport struct { - ID uint `json:"id"` - UserID uint `json:"user_id"` - AlertCount int `json:"alert_count"` - AnalysisTime int `json:"analysis_time"` - Predict string `json:"predict"` - Type string `json:"type"` - CreatedAt time.Time `json:"created_at"` + ID uint `json:"id"` + UserID uint `json:"user_id"` + AlertCount int `json:"alert_count"` + AnalysisTime int `json:"analysis_time"` + Type string `json:"type"` + Predict string `json:"predict"` + Score string `json:"score"` + NormalRatio string `json:"normal_ratio"` + NeckAngles string `json:"neck_angles"` + Distances string `json:"distances"` + StatusFrequencies string `json:"status_frequencies"` + CreatedAt time.Time `json:"created_at"` }