From 7a1ee41529ad8340c81382b82e37e74d106d8dd9 Mon Sep 17 00:00:00 2001 From: Yannik Schmidt Date: Tue, 28 May 2024 13:46:04 +0200 Subject: [PATCH 01/17] Add Theia spring profile and configuration file --- .../Artemis__Server__LocalVC___LocalCI__Theia_.xml | 13 +++++++++++++ .../de/tum/in/www1/artemis/config/Constants.java | 11 +++++++++++ src/main/resources/config/application-theia.yml | 2 ++ src/main/webapp/app/app.constants.ts | 2 ++ 4 files changed, 28 insertions(+) create mode 100644 .idea/runConfigurations/Artemis__Server__LocalVC___LocalCI__Theia_.xml create mode 100644 src/main/resources/config/application-theia.yml diff --git a/.idea/runConfigurations/Artemis__Server__LocalVC___LocalCI__Theia_.xml b/.idea/runConfigurations/Artemis__Server__LocalVC___LocalCI__Theia_.xml new file mode 100644 index 000000000000..cc1141eafb64 --- /dev/null +++ b/.idea/runConfigurations/Artemis__Server__LocalVC___LocalCI__Theia_.xml @@ -0,0 +1,13 @@ + + + + diff --git a/src/main/java/de/tum/in/www1/artemis/config/Constants.java b/src/main/java/de/tum/in/www1/artemis/config/Constants.java index 64aa8021e96d..80e591800c3f 100644 --- a/src/main/java/de/tum/in/www1/artemis/config/Constants.java +++ b/src/main/java/de/tum/in/www1/artemis/config/Constants.java @@ -305,6 +305,17 @@ public final class Constants { */ public static final String PROFILE_LTI = "lti"; + /** + * The name of the Spring profile used for Theia as an external online IDE. + */ + public static final String PROFILE_THEIA = "theia"; + + /** + * The InfoContributor's detail key for the Theia Portal URL + */ + + public static final String THEIA_PORTAL_URL = "theiaPortalURL"; + /** * Size of an unsigned tinyInt in SQL, that is used in the database */ diff --git a/src/main/resources/config/application-theia.yml b/src/main/resources/config/application-theia.yml new file mode 100644 index 000000000000..170aeeb61c8f --- /dev/null +++ b/src/main/resources/config/application-theia.yml @@ -0,0 +1,2 @@ +theia: + portal-url: http://theia-test.k8s.ase.cit.tum.de diff --git a/src/main/webapp/app/app.constants.ts b/src/main/webapp/app/app.constants.ts index e4adc90ebe57..c98f0ede797f 100644 --- a/src/main/webapp/app/app.constants.ts +++ b/src/main/webapp/app/app.constants.ts @@ -30,3 +30,5 @@ export const PROFILE_IRIS = 'iris'; export const PROFILE_LTI = 'lti'; export const PROFILE_ATHENA = 'athena'; + +export const PROFILE_THEIA = 'theia'; From 3ff2d16bef6655383933ed9a2062605a6db37bb2 Mon Sep 17 00:00:00 2001 From: Yannik Schmidt Date: Tue, 28 May 2024 13:47:26 +0200 Subject: [PATCH 02/17] Add InfoContributor for sharing Theia information with client --- .../service/theia/TheiaInfoContributor.java | 26 +++++++++++++++++++ .../layouts/profiles/profile-info.model.ts | 1 + .../layouts/profiles/profile.service.ts | 2 ++ 3 files changed, 29 insertions(+) create mode 100644 src/main/java/de/tum/in/www1/artemis/service/theia/TheiaInfoContributor.java diff --git a/src/main/java/de/tum/in/www1/artemis/service/theia/TheiaInfoContributor.java b/src/main/java/de/tum/in/www1/artemis/service/theia/TheiaInfoContributor.java new file mode 100644 index 000000000000..6df09afb63ef --- /dev/null +++ b/src/main/java/de/tum/in/www1/artemis/service/theia/TheiaInfoContributor.java @@ -0,0 +1,26 @@ +package de.tum.in.www1.artemis.service.theia; + +import static de.tum.in.www1.artemis.config.Constants.PROFILE_THEIA; + +import java.net.URL; + +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.actuate.info.Info; +import org.springframework.boot.actuate.info.InfoContributor; +import org.springframework.context.annotation.Profile; +import org.springframework.stereotype.Component; + +import de.tum.in.www1.artemis.config.Constants; + +@Profile(PROFILE_THEIA) +@Component +public class TheiaInfoContributor implements InfoContributor { + + @Value("${theia.portal-url}") + private URL theiaPortalURL; + + @Override + public void contribute(Info.Builder builder) { + builder.withDetail(Constants.THEIA_PORTAL_URL, theiaPortalURL); + } +} diff --git a/src/main/webapp/app/shared/layouts/profiles/profile-info.model.ts b/src/main/webapp/app/shared/layouts/profiles/profile-info.model.ts index 3eee461916ed..acebf864b323 100644 --- a/src/main/webapp/app/shared/layouts/profiles/profile-info.model.ts +++ b/src/main/webapp/app/shared/layouts/profiles/profile-info.model.ts @@ -54,6 +54,7 @@ export class ProfileInfo { }; }; }; + public theiaPortalURL: string; } export const hasEditableBuildPlan = (profileInfo: ProfileInfo): boolean => { diff --git a/src/main/webapp/app/shared/layouts/profiles/profile.service.ts b/src/main/webapp/app/shared/layouts/profiles/profile.service.ts index 13de97175c9d..ae501656b70f 100644 --- a/src/main/webapp/app/shared/layouts/profiles/profile.service.ts +++ b/src/main/webapp/app/shared/layouts/profiles/profile.service.ts @@ -82,6 +82,8 @@ export class ProfileService { profileInfo.git = data.git; + profileInfo.theiaPortalURL = data.theiaPortalURL ?? ''; + return profileInfo; }), ) From ab1cfca68f93af85a27e47df99737e54413c18bf Mon Sep 17 00:00:00 2001 From: Yannik Schmidt Date: Tue, 28 May 2024 13:52:13 +0200 Subject: [PATCH 03/17] Add button to open online iDE in exercise details for students --- ...ise-details-student-actions.component.html | 6 ++++ ...rcise-details-student-actions.component.ts | 33 +++++++++++++++++-- src/main/webapp/i18n/en/exercise-actions.json | 1 + 3 files changed, 38 insertions(+), 2 deletions(-) diff --git a/src/main/webapp/app/overview/exercise-details/exercise-details-student-actions.component.html b/src/main/webapp/app/overview/exercise-details/exercise-details-student-actions.component.html index 26d372f57d00..499412c29ae7 100644 --- a/src/main/webapp/app/overview/exercise-details/exercise-details-student-actions.component.html +++ b/src/main/webapp/app/overview/exercise-details/exercise-details-student-actions.component.html @@ -139,6 +139,12 @@ } + @if (theiaEnabled) { + + + + + } @if (exercise.allowFeedbackRequests) { @if (athenaEnabled) { { this.localVCEnabled = profileInfo.activeProfiles?.includes(PROFILE_LOCALVC); this.athenaEnabled = profileInfo.activeProfiles?.includes(PROFILE_ATHENA); + + // The online IDE is only available with correct SpringProfile and if it's enabled for this exercise + if (profileInfo.activeProfiles?.includes(PROFILE_THEIA)) { + this.theiaEnabled = true; + + // TODO: Check if exercise has Theia configured + + // Verify that Theia's portal URL is set in application-theia.yml + if (profileInfo.theiaPortalURL === '') { + this.theiaEnabled = false; + } else console.log('ProfilePortalURL:'); + console.log(profileInfo.theiaPortalURL); + } + + // Set and verify the online IDE's portal URL + this.theiaPortalURL = profileInfo.theiaPortalURL; + + // If the portal URL is invalid or not set, prevent the button from showing + if (this.theiaPortalURL === '') { + this.theiaEnabled = false; + } }); } else if (this.exercise.type === ExerciseType.MODELING) { this.editorLabel = 'openModelingEditor'; @@ -114,6 +139,10 @@ export class ExerciseDetailsStudentActionsComponent implements OnInit, OnChanges this.isTeamAvailable = !!(this.exercise.teamMode && this.exercise.studentAssignedTeamIdComputed && this.exercise.studentAssignedTeamId); } + getOnlineIDEURL() { + return this.theiaPortalURL; + } + receiveNewParticipation(newParticipation: StudentParticipation) { const studentParticipations = this.exercise.studentParticipations ?? []; if (studentParticipations.map((participation) => participation.id).includes(newParticipation.id)) { diff --git a/src/main/webapp/i18n/en/exercise-actions.json b/src/main/webapp/i18n/en/exercise-actions.json index 4b66719c93df..758dfe554dbb 100644 --- a/src/main/webapp/i18n/en/exercise-actions.json +++ b/src/main/webapp/i18n/en/exercise-actions.json @@ -23,6 +23,7 @@ "openModelingEditor": "Open modeling editor", "importIntoIDE": "Open in your IDE", "openRepository": "Open repository", + "openOnlineIDE": "Open online IDE", "practiceMode": { "title": "Practice Mode", "explanation": "The practice mode allows you to keep working on the exercise after the submission due date for self-practice. This will not affect your grading! Artemis will setup a separate repository for you to clone as usual.", From 5b54ac17568278c64cf501a01033704bc373d58f Mon Sep 17 00:00:00 2001 From: Yannik Schmidt Date: Wed, 29 May 2024 16:43:51 +0200 Subject: [PATCH 04/17] Switch from href usage to explicit Theia start function --- .../exercise-details-student-actions.component.html | 2 +- .../exercise-details-student-actions.component.ts | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/webapp/app/overview/exercise-details/exercise-details-student-actions.component.html b/src/main/webapp/app/overview/exercise-details/exercise-details-student-actions.component.html index 499412c29ae7..3aeae198d709 100644 --- a/src/main/webapp/app/overview/exercise-details/exercise-details-student-actions.component.html +++ b/src/main/webapp/app/overview/exercise-details/exercise-details-student-actions.component.html @@ -140,7 +140,7 @@ } @if (theiaEnabled) { - + diff --git a/src/main/webapp/app/overview/exercise-details/exercise-details-student-actions.component.ts b/src/main/webapp/app/overview/exercise-details/exercise-details-student-actions.component.ts index 0162c9149ee4..67fc9f31f89c 100644 --- a/src/main/webapp/app/overview/exercise-details/exercise-details-student-actions.component.ts +++ b/src/main/webapp/app/overview/exercise-details/exercise-details-student-actions.component.ts @@ -139,8 +139,8 @@ export class ExerciseDetailsStudentActionsComponent implements OnInit, OnChanges this.isTeamAvailable = !!(this.exercise.teamMode && this.exercise.studentAssignedTeamIdComputed && this.exercise.studentAssignedTeamId); } - getOnlineIDEURL() { - return this.theiaPortalURL; + startOnlineIDE() { + window.open(this.theiaPortalURL, '_blank'); } receiveNewParticipation(newParticipation: StudentParticipation) { From 11e63968cabc9799374a2b51166b1b323e01ad79 Mon Sep 17 00:00:00 2001 From: Yannik Schmidt Date: Wed, 29 May 2024 17:49:52 +0200 Subject: [PATCH 05/17] Add german translation --- src/main/webapp/i18n/de/exercise-actions.json | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/webapp/i18n/de/exercise-actions.json b/src/main/webapp/i18n/de/exercise-actions.json index cc6a63f1fac8..142359077c9d 100644 --- a/src/main/webapp/i18n/de/exercise-actions.json +++ b/src/main/webapp/i18n/de/exercise-actions.json @@ -22,6 +22,7 @@ "openModelingEditor": "Modellierungseditor öffnen", "importIntoIDE": "In deiner IDE öffnen", "openRepository": "Repository öffnen", + "openOnlineIDE": "Online IDE öffnen", "practiceMode": { "title": "Übungsmodus", "explanation": "Der Übungsmodus ermöglicht es dir nach der Einreichungsfrist zu Übungszwecken weiter an der Aufgabe zu arbeiten. Dies wird deine Bewertung nicht beeinflussen! Artemis wird dafür ein separates Repository aufsetzen, das du erneut clonen musst.", From 215d840ae672e2eee33102782bbedb1a85bc66e7 Mon Sep 17 00:00:00 2001 From: Yannik Schmidt Date: Wed, 29 May 2024 18:20:58 +0200 Subject: [PATCH 06/17] Clean up theia portal logic and add future work --- ...rcise-details-student-actions.component.ts | 20 ++++++++----------- 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/src/main/webapp/app/overview/exercise-details/exercise-details-student-actions.component.ts b/src/main/webapp/app/overview/exercise-details/exercise-details-student-actions.component.ts index 67fc9f31f89c..aea304fafd28 100644 --- a/src/main/webapp/app/overview/exercise-details/exercise-details-student-actions.component.ts +++ b/src/main/webapp/app/overview/exercise-details/exercise-details-student-actions.component.ts @@ -103,21 +103,17 @@ export class ExerciseDetailsStudentActionsComponent implements OnInit, OnChanges if (profileInfo.activeProfiles?.includes(PROFILE_THEIA)) { this.theiaEnabled = true; - // TODO: Check if exercise has Theia configured + // Set variables now, sanitze later on + this.theiaPortalURL = profileInfo.theiaPortalURL ?? ''; - // Verify that Theia's portal URL is set in application-theia.yml - if (profileInfo.theiaPortalURL === '') { + // Verify that Theia's portal URL is set + if (this.theiaPortalURL === '') { this.theiaEnabled = false; - } else console.log('ProfilePortalURL:'); - console.log(profileInfo.theiaPortalURL); - } - - // Set and verify the online IDE's portal URL - this.theiaPortalURL = profileInfo.theiaPortalURL; + } - // If the portal URL is invalid or not set, prevent the button from showing - if (this.theiaPortalURL === '') { - this.theiaEnabled = false; + // Future work: Verify that the course has Theia enabled + // Future work: Verify that the exercise has Theia enabled + // Future work: Verify that Theia has a valid blueprint to start up } }); } else if (this.exercise.type === ExerciseType.MODELING) { From 87d9c351ad3aba999c9bf28b30b0e1f56de2b755 Mon Sep 17 00:00:00 2001 From: Yannik Schmidt Date: Wed, 29 May 2024 18:21:47 +0200 Subject: [PATCH 07/17] Prevent missing theia config files from crashing Artemis --- .../tum/in/www1/artemis/service/theia/TheiaInfoContributor.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/de/tum/in/www1/artemis/service/theia/TheiaInfoContributor.java b/src/main/java/de/tum/in/www1/artemis/service/theia/TheiaInfoContributor.java index 6df09afb63ef..c88e92482a3d 100644 --- a/src/main/java/de/tum/in/www1/artemis/service/theia/TheiaInfoContributor.java +++ b/src/main/java/de/tum/in/www1/artemis/service/theia/TheiaInfoContributor.java @@ -16,7 +16,7 @@ @Component public class TheiaInfoContributor implements InfoContributor { - @Value("${theia.portal-url}") + @Value("${theia.portal-url:}") private URL theiaPortalURL; @Override From 96988cb7c12aec71e54ad9df89cc76b6e2b78bb3 Mon Sep 17 00:00:00 2001 From: Yannik Schmidt Date: Thu, 30 May 2024 14:12:29 +0200 Subject: [PATCH 08/17] Remove default values for theiaPortalURL --- .../tum/in/www1/artemis/service/theia/TheiaInfoContributor.java | 2 +- .../exercise-details-student-actions.component.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/de/tum/in/www1/artemis/service/theia/TheiaInfoContributor.java b/src/main/java/de/tum/in/www1/artemis/service/theia/TheiaInfoContributor.java index c88e92482a3d..6df09afb63ef 100644 --- a/src/main/java/de/tum/in/www1/artemis/service/theia/TheiaInfoContributor.java +++ b/src/main/java/de/tum/in/www1/artemis/service/theia/TheiaInfoContributor.java @@ -16,7 +16,7 @@ @Component public class TheiaInfoContributor implements InfoContributor { - @Value("${theia.portal-url:}") + @Value("${theia.portal-url}") private URL theiaPortalURL; @Override diff --git a/src/main/webapp/app/overview/exercise-details/exercise-details-student-actions.component.ts b/src/main/webapp/app/overview/exercise-details/exercise-details-student-actions.component.ts index aea304fafd28..9e43af785978 100644 --- a/src/main/webapp/app/overview/exercise-details/exercise-details-student-actions.component.ts +++ b/src/main/webapp/app/overview/exercise-details/exercise-details-student-actions.component.ts @@ -58,7 +58,7 @@ export class ExerciseDetailsStudentActionsComponent implements OnInit, OnChanges repositoryLink: string; theiaEnabled: boolean = false; - theiaPortalURL: string = ''; + theiaPortalURL: string; // Icons faFolderOpen = faFolderOpen; From ab37268eacc70f41af2cdc21d4826f090971d1a3 Mon Sep 17 00:00:00 2001 From: Yannik Schmidt Date: Thu, 30 May 2024 14:51:56 +0200 Subject: [PATCH 09/17] Add theiaPortalURL to profile test suite --- src/test/javascript/spec/service/profile.service.spec.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/test/javascript/spec/service/profile.service.spec.ts b/src/test/javascript/spec/service/profile.service.spec.ts index aedfe3bfb35d..6305d7ab221b 100644 --- a/src/test/javascript/spec/service/profile.service.spec.ts +++ b/src/test/javascript/spec/service/profile.service.spec.ts @@ -145,6 +145,7 @@ describe('Profile Service', () => { }, }, }, + theiaPortalURL: 'http://theia-test.k8s.ase.cit.tum.de', }; const expectedProfileInfo: ProfileInfo = { @@ -259,6 +260,7 @@ describe('Profile Service', () => { }, }, }, + theiaPortalURL: 'http://theia-test.k8s.ase.cit.tum.de', }; beforeEach(() => { From 44896b3a6a4481ed17bf9008082d66c9c0e59a41 Mon Sep 17 00:00:00 2001 From: Yannik Schmidt Date: Tue, 4 Jun 2024 15:19:37 +0200 Subject: [PATCH 10/17] Fix hard-coded client-side test --- src/main/resources/config/application-theia.yml | 2 +- .../spec/component/shared/clone-repo-button.component.spec.ts | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/resources/config/application-theia.yml b/src/main/resources/config/application-theia.yml index 170aeeb61c8f..4bd2953d6e4f 100644 --- a/src/main/resources/config/application-theia.yml +++ b/src/main/resources/config/application-theia.yml @@ -1,2 +1,2 @@ theia: - portal-url: http://theia-test.k8s.ase.cit.tum.de + portal-url: https://theia-test.k8s.ase.cit.tum.de diff --git a/src/test/javascript/spec/component/shared/clone-repo-button.component.spec.ts b/src/test/javascript/spec/component/shared/clone-repo-button.component.spec.ts index 34d3a93a5ec5..6ed448bdc622 100644 --- a/src/test/javascript/spec/component/shared/clone-repo-button.component.spec.ts +++ b/src/test/javascript/spec/component/shared/clone-repo-button.component.spec.ts @@ -75,6 +75,7 @@ describe('CloneRepoButtonComponent', () => { }, }, }, + theiaPortalURL: 'https://theia-test.k8s.ase.cit.tum.de', }; let participation: ProgrammingExerciseStudentParticipation = {}; From e4af6f0c14e59411344dc2ed0787dc84a7dae7c0 Mon Sep 17 00:00:00 2001 From: Yannik Schmidt Date: Thu, 6 Jun 2024 08:51:37 +0200 Subject: [PATCH 11/17] Add server-side test to cover TheiaInfoContributor --- .../theia/TheiaInfoContributorTest.java | 34 +++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 src/test/java/de/tum/in/www1/artemis/theia/TheiaInfoContributorTest.java diff --git a/src/test/java/de/tum/in/www1/artemis/theia/TheiaInfoContributorTest.java b/src/test/java/de/tum/in/www1/artemis/theia/TheiaInfoContributorTest.java new file mode 100644 index 000000000000..9650dacff353 --- /dev/null +++ b/src/test/java/de/tum/in/www1/artemis/theia/TheiaInfoContributorTest.java @@ -0,0 +1,34 @@ +package de.tum.in.www1.artemis.theia; + +import static de.tum.in.www1.artemis.config.Constants.PROFILE_THEIA; +import static org.assertj.core.api.Assertions.assertThat; + +import de.tum.in.www1.artemis.config.Constants; +import de.tum.in.www1.artemis.service.theia.TheiaInfoContributor; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.actuate.info.Info; +import org.springframework.context.annotation.Profile; + +@Profile(PROFILE_THEIA) +class TheiaInfoContributorTest { + + @Value("${theia.portal-url}") + private String expectedValue; + + TheiaInfoContributor theiaInfoContributor; + + @Test + void testContribute() { + Info.Builder builder = new Info.Builder(); + theiaInfoContributor = new TheiaInfoContributor(); + try { + theiaInfoContributor.contribute(builder); + } catch (NullPointerException e) { + } + + Info info = builder.build(); + assertThat(info.getDetails().get(Constants.THEIA_PORTAL_URL)).isEqualTo(expectedValue); + + } +} From dbbfa1c8c61a34dfc98e79cdd3cecb6babfdaae0 Mon Sep 17 00:00:00 2001 From: Yannik Schmidt Date: Thu, 6 Jun 2024 08:57:10 +0200 Subject: [PATCH 12/17] Add server-side test to cover TheiaInfoContributor --- .../in/www1/artemis/theia/TheiaInfoContributorTest.java | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/test/java/de/tum/in/www1/artemis/theia/TheiaInfoContributorTest.java b/src/test/java/de/tum/in/www1/artemis/theia/TheiaInfoContributorTest.java index 9650dacff353..04c75c487a6f 100644 --- a/src/test/java/de/tum/in/www1/artemis/theia/TheiaInfoContributorTest.java +++ b/src/test/java/de/tum/in/www1/artemis/theia/TheiaInfoContributorTest.java @@ -3,13 +3,14 @@ import static de.tum.in.www1.artemis.config.Constants.PROFILE_THEIA; import static org.assertj.core.api.Assertions.assertThat; -import de.tum.in.www1.artemis.config.Constants; -import de.tum.in.www1.artemis.service.theia.TheiaInfoContributor; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.actuate.info.Info; import org.springframework.context.annotation.Profile; +import de.tum.in.www1.artemis.config.Constants; +import de.tum.in.www1.artemis.service.theia.TheiaInfoContributor; + @Profile(PROFILE_THEIA) class TheiaInfoContributorTest { @@ -24,7 +25,8 @@ void testContribute() { theiaInfoContributor = new TheiaInfoContributor(); try { theiaInfoContributor.contribute(builder); - } catch (NullPointerException e) { + } + catch (NullPointerException e) { } Info info = builder.build(); From 236011d6e1ab964691a5f79cfcaae66cfd4d0b77 Mon Sep 17 00:00:00 2001 From: Yannik Schmidt Date: Thu, 6 Jun 2024 15:55:02 +0200 Subject: [PATCH 13/17] Add tests for checking the visibility of the Theia start button --- ...-details-student-actions.component.spec.ts | 50 +++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/src/test/javascript/spec/component/overview/exercise-details/exercise-details-student-actions.component.spec.ts b/src/test/javascript/spec/component/overview/exercise-details/exercise-details-student-actions.component.spec.ts index 75cc4e8a79b9..3f8e8c0ccc47 100644 --- a/src/test/javascript/spec/component/overview/exercise-details/exercise-details-student-actions.component.spec.ts +++ b/src/test/javascript/spec/component/overview/exercise-details/exercise-details-student-actions.component.spec.ts @@ -33,6 +33,7 @@ import { MockCourseExerciseService } from '../../../helpers/mocks/service/mock-c import { MockSyncStorage } from '../../../helpers/mocks/service/mock-sync-storage.service'; import { ArtemisTestModule } from '../../../test.module'; import { AssessmentType } from 'app/entities/assessment-type.model'; +import { PROFILE_THEIA } from 'app/app.constants'; describe('ExerciseDetailsStudentActionsComponent', () => { let comp: ExerciseDetailsStudentActionsComponent; @@ -598,4 +599,53 @@ describe('ExerciseDetailsStudentActionsComponent', () => { expect(window.alert).toHaveBeenCalledWith('artemisApp.exercise.maxAthenaResultsReached'); expect(result).toBeFalse(); }); + + it('start theia button should be visible when profile is active and url is set', () => { + getProfileInfoSub = jest.spyOn(profileService, 'getProfileInfo'); + getProfileInfoSub.mockReturnValue( + of({ + inProduction: false, + sshCloneURLTemplate: 'ssh://git@testserver.com:1234/', + activeProfiles: [PROFILE_THEIA], + theiaPortalURL: 'https://theia.test', + } as ProfileInfo), + ); + comp.exercise = exercise; + + fixture.detectChanges(); + + expect(comp.theiaEnabled).toBeTrue(); + }); + + it('start theia button should not be visible when profile is active but url is not set', () => { + getProfileInfoSub = jest.spyOn(profileService, 'getProfileInfo'); + getProfileInfoSub.mockReturnValue( + of({ + inProduction: false, + sshCloneURLTemplate: 'ssh://git@testserver.com:1234/', + activeProfiles: [PROFILE_THEIA], + } as ProfileInfo), + ); + comp.exercise = exercise; + + fixture.detectChanges(); + + expect(comp.theiaEnabled).toBeFalse(); + }); + + it('start theia button should not be visible when profile is not active but url is set', () => { + getProfileInfoSub = jest.spyOn(profileService, 'getProfileInfo'); + getProfileInfoSub.mockReturnValue( + of({ + inProduction: false, + sshCloneURLTemplate: 'ssh://git@testserver.com:1234/', + theiaPortalURL: 'https://theia.test', + } as ProfileInfo), + ); + comp.exercise = exercise; + + fixture.detectChanges(); + + expect(comp.theiaEnabled).toBeFalse(); + }); }); From 296fd2fc48d88e2c0360449a241230c1c70c1ec3 Mon Sep 17 00:00:00 2001 From: Yannik Schmidt Date: Thu, 6 Jun 2024 19:28:21 +0200 Subject: [PATCH 14/17] Combined test suite for client tests --- ...-details-student-actions.component.spec.ts | 62 +++++++------------ 1 file changed, 23 insertions(+), 39 deletions(-) diff --git a/src/test/javascript/spec/component/overview/exercise-details/exercise-details-student-actions.component.spec.ts b/src/test/javascript/spec/component/overview/exercise-details/exercise-details-student-actions.component.spec.ts index 3f8e8c0ccc47..c68055e75c4e 100644 --- a/src/test/javascript/spec/component/overview/exercise-details/exercise-details-student-actions.component.spec.ts +++ b/src/test/javascript/spec/component/overview/exercise-details/exercise-details-student-actions.component.spec.ts @@ -600,52 +600,36 @@ describe('ExerciseDetailsStudentActionsComponent', () => { expect(result).toBeFalse(); }); - it('start theia button should be visible when profile is active and url is set', () => { - getProfileInfoSub = jest.spyOn(profileService, 'getProfileInfo'); - getProfileInfoSub.mockReturnValue( - of({ - inProduction: false, - sshCloneURLTemplate: 'ssh://git@testserver.com:1234/', + it.each([ + [ + 'start theia button should be visible when profile is active and url is set', + { activeProfiles: [PROFILE_THEIA], theiaPortalURL: 'https://theia.test', - } as ProfileInfo), - ); - comp.exercise = exercise; - - fixture.detectChanges(); - - expect(comp.theiaEnabled).toBeTrue(); - }); - - it('start theia button should not be visible when profile is active but url is not set', () => { - getProfileInfoSub = jest.spyOn(profileService, 'getProfileInfo'); - getProfileInfoSub.mockReturnValue( - of({ - inProduction: false, - sshCloneURLTemplate: 'ssh://git@testserver.com:1234/', + }, + true, + ], + [ + 'start theia button should not be visible when profile is active but url is not set', + { activeProfiles: [PROFILE_THEIA], - } as ProfileInfo), - ); - comp.exercise = exercise; - - fixture.detectChanges(); - - expect(comp.theiaEnabled).toBeFalse(); - }); - - it('start theia button should not be visible when profile is not active but url is set', () => { - getProfileInfoSub = jest.spyOn(profileService, 'getProfileInfo'); - getProfileInfoSub.mockReturnValue( - of({ - inProduction: false, - sshCloneURLTemplate: 'ssh://git@testserver.com:1234/', + }, + false, + ], + [ + 'start theia button should not be visible when profile is not active but url is set', + { theiaPortalURL: 'https://theia.test', - } as ProfileInfo), - ); + }, + false, + ], + ])('%s', (description, profileInfo, expectedVisibility) => { + getProfileInfoSub = jest.spyOn(profileService, 'getProfileInfo'); + getProfileInfoSub.mockReturnValue(of(profileInfo as ProfileInfo)); comp.exercise = exercise; fixture.detectChanges(); - expect(comp.theiaEnabled).toBeFalse(); + expect(comp.theiaEnabled).toBe(expectedVisibility); }); }); From bdb00e1a26d0e8c2bf1b471f47b3bb7359ee9582 Mon Sep 17 00:00:00 2001 From: Yannik Schmidt Date: Mon, 24 Jun 2024 11:17:07 +0200 Subject: [PATCH 15/17] Use exemplary values in configuration --- src/main/resources/config/application-dev.yml | 4 ++++ src/main/resources/config/application-theia.yml | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/main/resources/config/application-dev.yml b/src/main/resources/config/application-dev.yml index 62a9bda7c416..242f427c6a8e 100644 --- a/src/main/resources/config/application-dev.yml +++ b/src/main/resources/config/application-dev.yml @@ -126,3 +126,7 @@ eureka: enabled: false # By default, the JHipster Registry is not used in the "dev" profile service-url: defaultZone: http://admin:${jhipster.registry.password}@localhost:8761/eureka/ + +# Theia configuration +theia: + portal-url: https://theia-test.k8s.ase.cit.tum.de diff --git a/src/main/resources/config/application-theia.yml b/src/main/resources/config/application-theia.yml index 4bd2953d6e4f..2b8e1346d008 100644 --- a/src/main/resources/config/application-theia.yml +++ b/src/main/resources/config/application-theia.yml @@ -1,2 +1,2 @@ theia: - portal-url: https://theia-test.k8s.ase.cit.tum.de + portal-url: https://your-theia-instance.com From 4eb4919e9b09227da6efc44812cc60d9401b5071 Mon Sep 17 00:00:00 2001 From: Yannik Schmidt Date: Mon, 24 Jun 2024 11:23:29 +0200 Subject: [PATCH 16/17] Remove future work comments --- .../exercise-details-student-actions.component.ts | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/main/webapp/app/overview/exercise-details/exercise-details-student-actions.component.ts b/src/main/webapp/app/overview/exercise-details/exercise-details-student-actions.component.ts index c760e5baa3e4..8453e998e8f9 100644 --- a/src/main/webapp/app/overview/exercise-details/exercise-details-student-actions.component.ts +++ b/src/main/webapp/app/overview/exercise-details/exercise-details-student-actions.component.ts @@ -112,17 +112,13 @@ export class ExerciseDetailsStudentActionsComponent implements OnInit, OnChanges if (profileInfo.activeProfiles?.includes(PROFILE_THEIA)) { this.theiaEnabled = true; - // Set variables now, sanitze later on + // Set variables now, sanitize later on this.theiaPortalURL = profileInfo.theiaPortalURL ?? ''; // Verify that Theia's portal URL is set if (this.theiaPortalURL === '') { this.theiaEnabled = false; } - - // Future work: Verify that the course has Theia enabled - // Future work: Verify that the exercise has Theia enabled - // Future work: Verify that Theia has a valid blueprint to start up } }); } else if (this.exercise.type === ExerciseType.MODELING) { From 8e5fb2099b26ba2cbb1e4945e91550fc10345239 Mon Sep 17 00:00:00 2001 From: Yannik Schmidt Date: Mon, 24 Jun 2024 11:26:33 +0200 Subject: [PATCH 17/17] Fix order of execution in IntelliJ theia profile --- ...mis__Server__LocalVC___LocalCI__Theia_.xml | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/.idea/runConfigurations/Artemis__Server__LocalVC___LocalCI__Theia_.xml b/.idea/runConfigurations/Artemis__Server__LocalVC___LocalCI__Theia_.xml index cc1141eafb64..89ddf1952a14 100644 --- a/.idea/runConfigurations/Artemis__Server__LocalVC___LocalCI__Theia_.xml +++ b/.idea/runConfigurations/Artemis__Server__LocalVC___LocalCI__Theia_.xml @@ -1,13 +1,13 @@ - - + \ No newline at end of file