diff --git a/src/main/webapp/app/course/manage/course-management.service.ts b/src/main/webapp/app/course/manage/course-management.service.ts index 6b1a0a567412..0f442cada5ea 100644 --- a/src/main/webapp/app/course/manage/course-management.service.ts +++ b/src/main/webapp/app/course/manage/course-management.service.ts @@ -676,7 +676,7 @@ export class CourseManagementService { this.entityTitleService.setTitle(EntityType.COURSE, [course?.id], course?.title); course?.exercises?.forEach((exercise) => { - this.entityTitleService.setTitle(EntityType.EXERCISE, [exercise.id], exercise.title); + this.entityTitleService.setExerciseTitle(exercise); }); course?.lectures?.forEach((lecture) => this.entityTitleService.setTitle(EntityType.LECTURE, [lecture.id], lecture.title)); course?.exams?.forEach((exam) => this.entityTitleService.setTitle(EntityType.EXAM, [exam.id], exam.title)); diff --git a/src/main/webapp/app/exercises/programming/manage/services/programming-exercise-participation.service.ts b/src/main/webapp/app/exercises/programming/manage/services/programming-exercise-participation.service.ts index 5953571a4190..e5ece788a0fb 100644 --- a/src/main/webapp/app/exercises/programming/manage/services/programming-exercise-participation.service.ts +++ b/src/main/webapp/app/exercises/programming/manage/services/programming-exercise-participation.service.ts @@ -3,11 +3,11 @@ import { Injectable } from '@angular/core'; import { AccountService } from 'app/core/auth/account.service'; import { Participation } from 'app/entities/participation/participation.model'; import { ProgrammingExerciseStudentParticipation } from 'app/entities/participation/programming-exercise-student-participation.model'; +import { CommitInfo } from 'app/entities/programming/programming-submission.model'; import { Result } from 'app/entities/result.model'; import { EntityTitleService, EntityType } from 'app/shared/layouts/navbar/entity-title.service'; import { createRequestOption } from 'app/shared/util/request.util'; import { Observable, map, tap } from 'rxjs'; -import { CommitInfo } from 'app/entities/programming/programming-submission.model'; export interface IProgrammingExerciseParticipationService { getLatestResultWithFeedback: (participationId: number, withSubmission: boolean) => Observable; @@ -81,7 +81,7 @@ export class ProgrammingExerciseParticipationService implements IProgrammingExer sendTitlesToEntityTitleService(participation: Participation | undefined) { if (participation?.exercise) { const exercise = participation.exercise; - this.entityTitleService.setTitle(EntityType.EXERCISE, [exercise.id], exercise.title); + this.entityTitleService.setExerciseTitle(exercise); if (exercise.course) { const course = exercise.course; diff --git a/src/main/webapp/app/exercises/shared/exercise/exercise.service.ts b/src/main/webapp/app/exercises/shared/exercise/exercise.service.ts index a5c6b2febc1a..909aa30aa592 100644 --- a/src/main/webapp/app/exercises/shared/exercise/exercise.service.ts +++ b/src/main/webapp/app/exercises/shared/exercise/exercise.service.ts @@ -488,12 +488,8 @@ export class ExerciseService { } public sendExerciseTitleToTitleService(exercise?: Exercise) { - // we only want to show the exercise group name as exercise name to the student for exam exercises. - // for tutors and more privileged users, we want to show the exercise title - if (exercise?.exerciseGroup && !exercise?.isAtLeastTutor) { - this.entityTitleService.setTitle(EntityType.EXERCISE, [exercise?.id], exercise?.exerciseGroup.title); - } else { - this.entityTitleService.setTitle(EntityType.EXERCISE, [exercise?.id], exercise?.title); + if (exercise) { + this.entityTitleService.setExerciseTitle(exercise); } if (exercise?.course) { this.entityTitleService.setTitle(EntityType.COURSE, [exercise.course.id], exercise.course.title); diff --git a/src/main/webapp/app/shared/layouts/navbar/entity-title.service.ts b/src/main/webapp/app/shared/layouts/navbar/entity-title.service.ts index d342f8eb1464..a50aab27ddc4 100644 --- a/src/main/webapp/app/shared/layouts/navbar/entity-title.service.ts +++ b/src/main/webapp/app/shared/layouts/navbar/entity-title.service.ts @@ -1,6 +1,7 @@ import { HttpClient, HttpResponse } from '@angular/common/http'; import { Injectable } from '@angular/core'; import { captureException } from '@sentry/angular'; +import { Exercise } from 'app/entities/exercise.model'; import { EMPTY, Observable, ReplaySubject, Subject } from 'rxjs'; export enum EntityType { @@ -88,6 +89,16 @@ export class EntityTitleService { } } + public setExerciseTitle(exercise: Exercise) { + // we only want to show the exercise group name as exercise name to the students for exam exercises. + // for tutors and more privileged users, we want to show the exercise title + if (exercise.exerciseGroup && !exercise?.isAtLeastTutor) { + this.setTitle(EntityType.EXERCISE, [exercise.id], exercise.exerciseGroup.title); + } else { + this.setTitle(EntityType.EXERCISE, [exercise.id], exercise.title); + } + } + /** * Fetches the title of the given entity from the server. * diff --git a/src/test/javascript/spec/service/entity-title.service.spec.ts b/src/test/javascript/spec/service/entity-title.service.spec.ts index 1e8165930ba7..a0d25c344ae6 100644 --- a/src/test/javascript/spec/service/entity-title.service.spec.ts +++ b/src/test/javascript/spec/service/entity-title.service.spec.ts @@ -1,3 +1,4 @@ +import { Exercise } from 'app/entities/exercise.model'; import { EntityTitleService, EntityType } from 'app/shared/layouts/navbar/entity-title.service'; import { TestBed, fakeAsync, tick } from '@angular/core/testing'; import { MockHttpService } from '../helpers/mocks/service/mock-http.service'; @@ -115,4 +116,34 @@ describe('EntityTitleService', () => { service.setTitle(type, ids, title); expect(captureSpy).toHaveBeenCalledOnce(); }); + + it('sets the exercise group title for students during an exam', () => { + const exercise = { id: 1, exerciseGroup: { title: 'Group Title' }, isAtLeastTutor: false } as Exercise; + service.setExerciseTitle(exercise); + + let result: string | undefined = undefined; + service.getTitle(EntityType.EXERCISE, [1]).subscribe((title) => (result = title)); + + expect(result).toBe('Group Title'); + }); + + it('sets the exercise title for tutors and more privileged users', () => { + const exercise = { id: 1, exerciseGroup: { title: 'Group Title' }, isAtLeastTutor: true, title: 'Exercise Title' } as Exercise; + service.setExerciseTitle(exercise); + + let result: string | undefined = undefined; + service.getTitle(EntityType.EXERCISE, [1]).subscribe((title) => (result = title)); + + expect(result).toBe('Exercise Title'); + }); + + it('sets the exercise title for course exercises', () => { + const exercise = { id: 1, isAtLeastTutor: false, title: 'Exercise Title' } as Exercise; + service.setExerciseTitle(exercise); + + let result: string | undefined = undefined; + service.getTitle(EntityType.EXERCISE, [1]).subscribe((title) => (result = title)); + + expect(result).toBe('Exercise Title'); + }); }); diff --git a/src/test/javascript/spec/service/exercise.service.spec.ts b/src/test/javascript/spec/service/exercise.service.spec.ts index 415078a437e1..3213088306c1 100644 --- a/src/test/javascript/spec/service/exercise.service.spec.ts +++ b/src/test/javascript/spec/service/exercise.service.spec.ts @@ -22,7 +22,7 @@ import { SafeHtml } from '@angular/platform-browser'; import { ExerciseCategory } from 'app/entities/exercise-category.model'; import { Observable } from 'rxjs'; import { AccountService } from 'app/core/auth/account.service'; -import { EntityTitleService, EntityType } from 'app/shared/layouts/navbar/entity-title.service'; +import { EntityTitleService } from 'app/shared/layouts/navbar/entity-title.service'; import { ProfileService } from 'app/shared/layouts/profiles/profile.service'; describe('Exercise Service', () => { @@ -358,7 +358,7 @@ describe('Exercise Service', () => { const profileService = TestBed.inject(ProfileService); const accountServiceSpy = jest.spyOn(accountService, 'setAccessRightsForExerciseAndReferencedCourse'); - const entityTitleServiceSpy = jest.spyOn(entityTitleService, 'setTitle'); + const entityTitleServiceSpy = jest.spyOn(entityTitleService, 'setExerciseTitle'); const profileServiceSpy = jest.spyOn(profileService, 'getProfileInfo'); const category = { @@ -387,7 +387,7 @@ describe('Exercise Service', () => { expect(accountServiceSpy).toHaveBeenCalledWith(expect.objectContaining({ id: exerciseFromServer.id })); expect(entityTitleServiceSpy).toHaveBeenCalledOnce(); - expect(entityTitleServiceSpy).toHaveBeenCalledWith(EntityType.EXERCISE, [exerciseFromServer.id], exerciseFromServer.title); + expect(entityTitleServiceSpy).toHaveBeenCalledWith(exerciseFromServer); expect(profileServiceSpy).not.toHaveBeenCalled(); }); @@ -520,23 +520,4 @@ describe('Exercise Service', () => { method: 'PUT', }); }); - - it('should correctly send the exercise name to the title service', () => { - const entityTitleService = TestBed.inject(EntityTitleService); - const examExerciseForStudent = { id: 1, title: 'exercise', exerciseGroup: { id: 1, title: 'exercise group' } } as Exercise; - const examExerciseForTutor = { ...examExerciseForStudent, isAtLeastTutor: true } as Exercise; - const courseExerciseForStudent = { ...examExerciseForStudent, exerciseGroup: undefined, course: { id: 2, title: 'course' } } as Exercise; - const courseExerciseForTutor = { ...courseExerciseForStudent, isAtLeastTutor: true } as Exercise; - const entityTitleServiceSpy = jest.spyOn(entityTitleService, 'setTitle'); - service.sendExerciseTitleToTitleService(examExerciseForStudent); - expect(entityTitleServiceSpy).toHaveBeenCalledWith(EntityType.EXERCISE, [1], 'exercise group'); - service.sendExerciseTitleToTitleService(examExerciseForTutor); - expect(entityTitleServiceSpy).toHaveBeenCalledWith(EntityType.EXERCISE, [1], 'exercise'); - service.sendExerciseTitleToTitleService(courseExerciseForStudent); - expect(entityTitleServiceSpy).toHaveBeenCalledWith(EntityType.EXERCISE, [1], 'exercise'); - expect(entityTitleServiceSpy).toHaveBeenCalledWith(EntityType.COURSE, [2], 'course'); - service.sendExerciseTitleToTitleService(courseExerciseForTutor); - expect(entityTitleServiceSpy).toHaveBeenCalledWith(EntityType.EXERCISE, [1], 'exercise'); - expect(entityTitleServiceSpy).toHaveBeenCalledWith(EntityType.COURSE, [2], 'course'); - }); });