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

Assessment: Do not display automatic as additional feedback in the online code editor #10120

Merged
merged 8 commits into from
Jan 12, 2025
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import { ButtonType } from 'app/shared/components/button.component';
import { Result } from 'app/entities/result.model';
import { AccountService } from 'app/core/auth/account.service';
import { getFirstResultWithComplaint, getLatestSubmissionResult } from 'app/entities/submission.model';
import { addParticipationToResult, getUnreferencedFeedback } from 'app/exercises/shared/result/result.utils';
import { addParticipationToResult, getManualUnreferencedFeedback } from 'app/exercises/shared/result/result.utils';
import { Feedback, checkSubsequentFeedbackInAssessment } from 'app/entities/feedback.model';
import { onError } from 'app/shared/util/global.utils';
import { getCourseFromExercise } from 'app/entities/exercise.model';
Expand Down Expand Up @@ -247,7 +247,7 @@ export class FileUploadSubmissionComponent implements OnInit, ComponentCanDeacti
get unreferencedFeedback(): Feedback[] | undefined {
if (this.result?.feedbacks) {
checkSubsequentFeedbackInAssessment(this.result.feedbacks);
return getUnreferencedFeedback(this.result.feedbacks);
return getManualUnreferencedFeedback(this.result.feedbacks);
}
return undefined;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import { ModelingAssessmentService } from 'app/exercises/modeling/assess/modelin
import { ModelingSubmissionService } from 'app/exercises/modeling/participate/modeling-submission.service';
import { ModelingEditorComponent } from 'app/exercises/modeling/shared/modeling-editor.component';
import { getExerciseDueDate, hasExerciseDueDatePassed } from 'app/exercises/shared/exercise/exercise.utils';
import { addParticipationToResult, getUnreferencedFeedback } from 'app/exercises/shared/result/result.utils';
import { addParticipationToResult, getAutomaticUnreferencedFeedback } from 'app/exercises/shared/result/result.utils';
import { AccountService } from 'app/core/auth/account.service';
import { GuidedTourService } from 'app/guided-tour/guided-tour.service';
import { modelingTour } from 'app/guided-tour/tours/modeling-tour';
Expand Down Expand Up @@ -664,7 +664,7 @@ export class ModelingSubmissionComponent implements OnInit, OnDestroy, Component
get unreferencedFeedback(): Feedback[] | undefined {
if (this.assessmentResult?.feedbacks) {
checkSubsequentFeedbackInAssessment(this.assessmentResult.feedbacks);
return getUnreferencedFeedback(this.assessmentResult.feedbacks);
return getAutomaticUnreferencedFeedback(this.assessmentResult.feedbacks);
}
return undefined;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import { DomainType } from 'app/exercises/programming/shared/code-editor/model/c
import { ActivatedRoute } from '@angular/router';
import { CodeEditorContainerComponent } from 'app/exercises/programming/shared/code-editor/container/code-editor-container.component';
import { ProgrammingExerciseStudentParticipation } from 'app/entities/participation/programming-exercise-student-participation.model';
import { getUnreferencedFeedback } from 'app/exercises/shared/result/result.utils';
import { getManualUnreferencedFeedback } from 'app/exercises/shared/result/result.utils';
import { SubmissionType } from 'app/entities/submission.model';
import { SubmissionPolicyType } from 'app/entities/submission-policy.model';
import { Course } from 'app/entities/course.model';
Expand Down Expand Up @@ -160,7 +160,7 @@ export class CodeEditorStudentContainerComponent implements OnInit, OnDestroy {
get unreferencedFeedback(): Feedback[] {
if (this.latestResult?.feedbacks) {
checkSubsequentFeedbackInAssessment(this.latestResult.feedbacks);
return getUnreferencedFeedback(this.latestResult.feedbacks) ?? [];
return getManualUnreferencedFeedback(this.latestResult.feedbacks) ?? [];
}
return [];
}
Expand Down
19 changes: 12 additions & 7 deletions src/main/webapp/app/exercises/shared/result/result.utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -116,16 +116,21 @@ export const addParticipationToResult = (result: Result | undefined, participati
};

/**
* searches for all unreferenced feedback in an array of feedbacks of a result
* searches for all manual unreferenced feedback in an array of feedbacks of a result
* @param feedbacks the feedback of a result
* @returns an array with the unreferenced feedback of the result
*/
export const getUnreferencedFeedback = (feedbacks: Feedback[] | undefined): Feedback[] | undefined => {
return feedbacks
? feedbacks.filter(
(feedbackElement) => !feedbackElement.reference && (feedbackElement.type === FeedbackType.MANUAL_UNREFERENCED || feedbackElement.type === FeedbackType.AUTOMATIC),
)
: undefined;
export const getManualUnreferencedFeedback = (feedbacks: Feedback[] | undefined): Feedback[] | undefined => {
return feedbacks ? feedbacks.filter((feedbackElement) => !feedbackElement.reference && feedbackElement.type === FeedbackType.MANUAL_UNREFERENCED) : undefined;
};

/**
* searches for all automatic unreferenced feedback in an array of feedbacks of a result
* @param feedbacks the feedback of a result
* @returns an array with the unreferenced feedback of the result
*/
export const getAutomaticUnreferencedFeedback = (feedbacks: Feedback[] | undefined): Feedback[] | undefined => {
return feedbacks ? feedbacks.filter((feedbackElement) => !feedbackElement.reference && feedbackElement.type === FeedbackType.AUTOMATIC) : undefined;
};

export function isAIResultAndFailed(result: Result | undefined): boolean {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import { TextSubmission } from 'app/entities/text/text-submission.model';
import { StringCountService } from 'app/exercises/text/participate/string-count.service';
import { AccountService } from 'app/core/auth/account.service';
import { getFirstResultWithComplaint, getLatestSubmissionResult, setLatestSubmissionResult } from 'app/entities/submission.model';
import { getUnreferencedFeedback, isAthenaAIResult } from 'app/exercises/shared/result/result.utils';
import { getManualUnreferencedFeedback, isAthenaAIResult } from 'app/exercises/shared/result/result.utils';
import { onError } from 'app/shared/util/global.utils';
import { Course } from 'app/entities/course.model';
import { getCourseFromExercise } from 'app/entities/exercise.model';
Expand Down Expand Up @@ -312,7 +312,7 @@ export class TextEditorComponent implements OnInit, OnDestroy, ComponentCanDeact
* Check whether or not a result exists and if, returns the unreferenced feedback of it
*/
get unreferencedFeedback(): Feedback[] | undefined {
return this.result ? getUnreferencedFeedback(this.result.feedbacks) : undefined;
return this.result ? getManualUnreferencedFeedback(this.result.feedbacks) : undefined;
}

get wordCount(): number {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -802,7 +802,7 @@ void requestModelingFeedbackSuccess_withAthenaFailure() throws Exception {

request.putWithResponseBody("/api/exercises/" + modelingExercise.getId() + "/request-feedback", null, StudentParticipation.class, HttpStatus.OK);

verify(resultWebsocketService, timeout(2000).times(1)).broadcastNewResult(any(), resultCaptor.capture());
verify(resultWebsocketService, timeout(2000).times(2)).broadcastNewResult(any(), resultCaptor.capture());

Result invokedModelingResult = resultCaptor.getAllValues().getFirst();
assertThat(invokedModelingResult).isNotNull();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -505,7 +505,7 @@ describe('ModelingSubmissionComponent', () => {
detailText: 'feedback1',
credits: 1,
gradingInstruction,
type: FeedbackType.MANUAL_UNREFERENCED,
type: FeedbackType.AUTOMATIC,
} as Feedback,
{
id: 2,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -706,7 +706,7 @@ describe('ModelingSubmissionComponent', () => {
detailText: 'feedback1',
credits: 1,
gradingInstruction,
type: FeedbackType.MANUAL_UNREFERENCED,
type: FeedbackType.AUTOMATIC,
} as Feedback,
{
id: 2,
Expand Down
27 changes: 23 additions & 4 deletions src/test/javascript/spec/component/utils/result.utils.spec.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import {
ResultTemplateStatus,
breakCircularResultBackReferences,
getAutomaticUnreferencedFeedback,
getManualUnreferencedFeedback,
getResultIconClass,
getTextColorClass,
getUnreferencedFeedback,
isOnlyCompilationTested,
} from 'app/exercises/shared/result/result.utils';
import { Feedback, FeedbackType, STATIC_CODE_ANALYSIS_FEEDBACK_IDENTIFIER } from 'app/entities/feedback.model';
Expand All @@ -18,12 +19,30 @@ import { Result } from 'app/entities/result.model';
import dayjs from 'dayjs/esm';

describe('ResultUtils', () => {
it('should filter out all non unreferenced feedbacks', () => {
const feedbacks = [{ reference: 'foo' }, { reference: 'foo', type: FeedbackType.MANUAL_UNREFERENCED }, { type: FeedbackType.MANUAL_UNREFERENCED }, {}];
const unreferencedFeedbacks = getUnreferencedFeedback(feedbacks);
it('should filter out all non unreferenced feedbacks that do not have type MANUAL_UNREFERENCED', () => {
const feedbacks = [
{ reference: 'foo' },
{ reference: 'foo', type: FeedbackType.MANUAL_UNREFERENCED },
{ type: FeedbackType.AUTOMATIC },
{ type: FeedbackType.MANUAL_UNREFERENCED },
{},
];
const unreferencedFeedbacks = getManualUnreferencedFeedback(feedbacks);
expect(unreferencedFeedbacks).toEqual([{ type: FeedbackType.MANUAL_UNREFERENCED }]);
});

it('should filter out all non unreferenced feedbacks that do not have type AUTOMATIC', () => {
const feedbacks = [
{ reference: 'foo' },
{ reference: 'foo', type: FeedbackType.AUTOMATIC },
{ type: FeedbackType.AUTOMATIC },
{ type: FeedbackType.MANUAL_UNREFERENCED },
{},
];
const unreferencedFeedbacks = getAutomaticUnreferencedFeedback(feedbacks);
expect(unreferencedFeedbacks).toEqual([{ type: FeedbackType.AUTOMATIC }]);
});

it.each([
{
result: {
Expand Down
Loading