Skip to content

Commit

Permalink
Development: Disable LTI exercise link button when no exercise is sel…
Browse files Browse the repository at this point in the history
…ected (#9077)
  • Loading branch information
iyannsch committed Jul 20, 2024
1 parent 2aef342 commit 853cade
Show file tree
Hide file tree
Showing 5 changed files with 27 additions and 6 deletions.
12 changes: 9 additions & 3 deletions src/main/webapp/app/lti/lti13-deep-linking.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -75,9 +75,15 @@ <h4 class="modal-title" jhiTranslate="artemisApp.lti13.selectContentFromCourse"
</div>
<div class="modal-footer">
<div>
<button type="submit" (click)="sendDeepLinkRequest()" class="btn btn-success">
<span class="d-sm-inline" jhiTranslate="artemisApp.lti13.deepLinking.link"></span>
</button>
@if (selectedExercises?.size) {
<button type="submit" (click)="sendDeepLinkRequest()" class="btn btn-success">
<span class="d-sm-inline" jhiTranslate="artemisApp.lti13.deepLinking.link"></span>
</button>
} @else {
<button type="submit" class="btn btn-success disabled">
<span class="d-sm-inline" jhiTranslate="artemisApp.lti13.deepLinking.selectToLink"></span>
</button>
}
</div>
</div>
</div>
Expand Down
4 changes: 3 additions & 1 deletion src/main/webapp/app/lti/lti13-deep-linking.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ export class Lti13DeepLinkingComponent implements OnInit {
* If an exercise is selected, it sends a POST request to initiate deep linking.
*/
sendDeepLinkRequest() {
if (this.selectedExercises) {
if (this.selectedExercises?.size) {
const ltiIdToken = this.sessionStorageService.retrieve('ltiIdToken') ?? '';
const clientRegistrationId = this.sessionStorageService.retrieve('clientRegistrationId') ?? '';
const exerciseIds = Array.from(this.selectedExercises).join(',');
Expand All @@ -154,6 +154,8 @@ export class Lti13DeepLinkingComponent implements OnInit {
onError(this.alertService, error);
},
});
} else {
this.alertService.error('artemisApp.lti13.deepLinking.selectToLink');
}
}
}
1 change: 1 addition & 0 deletions src/main/webapp/i18n/de/lti.json
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@
"linkedSuccessfully": "Verknüpfung der Übungen erfolgreich",
"linkedFailed": "Fehler beim Deep-Linking",
"link": "Verlinken",
"selectToLink": "Übungen zum Verlinken auswählen",
"unknownError": "Aufgrund eines unbekannten Fehlers nicht erfolgreich. Bitte kontaktiere einen Admin!",
"noCoursesError": "Keiner deiner Artemis-Kurse hat LTI aktiviert. Bitte fahre mit der Konfiguration mindestens eines Kurses fort.",
"learnMore": "Erfahre mehr über die Einrichtung von LTI in einem Kurs.."
Expand Down
1 change: 1 addition & 0 deletions src/main/webapp/i18n/en/lti.json
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@
"linkedSuccessfully": "Linked exercises successfully",
"linkedFailed": "Error during deep linking",
"link": "Link",
"selectToLink": "Select exercises to link",
"unknownError": "Unsuccessful due to an unknown error. Please contact an admin!",
"noCoursesError": "You do not have any LTI-enabled courses in Artemis yet. Please configure at least one course to use this feature.",
"learnMore": "Learn more about enabling LTI in your course.."
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { AccountService } from 'app/core/auth/account.service';
import { SortService } from 'app/shared/service/sort.service';
import { of, throwError } from 'rxjs';
import { ArtemisTranslatePipe } from 'app/shared/pipes/artemis-translate.pipe';
import { MockPipe, MockProvider } from 'ng-mocks';
import { MockPipe } from 'ng-mocks';
import { User } from 'app/core/user/user.model';
import { Course } from 'app/entities/course.model';
import { Exercise, ExerciseType } from 'app/entities/exercise.model';
Expand All @@ -27,6 +27,7 @@ describe('Lti13DeepLinkingComponent', () => {
const courseManagementServiceMock = { findWithExercises: jest.fn() };
const accountServiceMock = { identity: jest.fn(), getAuthenticationState: jest.fn() };
const sortServiceMock = { sortByProperty: jest.fn() };
const alertServiceMock = { error: jest.fn(), addAlert: jest.fn() };

const exercise1 = { id: 1, shortName: 'git', type: ExerciseType.PROGRAMMING } as Exercise;
const exercise2 = { id: 2, shortName: 'test', type: ExerciseType.PROGRAMMING } as Exercise;
Expand All @@ -46,7 +47,7 @@ describe('Lti13DeepLinkingComponent', () => {
{ provide: AccountService, useValue: accountServiceMock },
{ provide: SortService, useValue: sortServiceMock },
{ provide: SessionStorageService, useClass: MockSyncStorage },
MockProvider(AlertService),
{ provide: AlertService, useValue: alertServiceMock },
],
}).compileComponents();
jest.spyOn(console, 'error').mockImplementation(() => {});
Expand Down Expand Up @@ -76,6 +77,16 @@ describe('Lti13DeepLinkingComponent', () => {
expect(component.exercises).toContainAllValues(course.exercises!);
}));

it('should alert user when no exercise is selected', () => {
component.selectedExercises = undefined;
component.sendDeepLinkRequest();
expect(alertServiceMock.error).toHaveBeenCalledWith('artemisApp.lti13.deepLinking.selectToLink');

component.selectedExercises = new Set();
component.sendDeepLinkRequest();
expect(alertServiceMock.error).toHaveBeenNthCalledWith(2, 'artemisApp.lti13.deepLinking.selectToLink');
});

it('should navigate on init when user is authenticated', fakeAsync(() => {
const redirectSpy = jest.spyOn(component, 'redirectUserToLoginThenTargetLink');
accountServiceMock.identity.mockResolvedValue(undefined);
Expand Down

0 comments on commit 853cade

Please sign in to comment.