-
Notifications
You must be signed in to change notification settings - Fork 302
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
Programming exercises
: Improve code button
#10147
base: develop
Are you sure you want to change the base?
Programming exercises
: Improve code button
#10147
Conversation
…re/update-angular19
…re/update-angular19
…re/update-angular19
…re/update-angular19
…re/update-angular19
To fix pdf-preview-enlarged-canvas.component.spec.ts tests and pdf-preview-thumbnail-grid.component.spec.ts tests
…re/update-angular19
26dd829
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
🧹 Nitpick comments (4)
src/main/webapp/app/shared/components/code-button/code-button.component.ts (3)
85-86
: Extract localStorage key as a constant.The localStorage key 'code-button-state' is hardcoded in multiple places. Extract it as a constant for better maintainability.
+private readonly LOCAL_STORAGE_KEY = 'code-button-state'; private storeToLocalStorage() { - this.localStorage.store('code-button-state', this.currentState); + this.localStorage.store(this.LOCAL_STORAGE_KEY, this.currentState); }Also applies to: 209-210
85-86
: Initialize currentState in constructor.The
currentState
initialization from localStorage should be moved to the constructor for better state management.constructor() { this.isInCourseManagement = this.router.url.includes('course-management'); + this.currentState = this.localStorage.retrieve(this.LOCAL_STORAGE_KEY) || States.Password; effect(async () => { // ... }); } onClick() { - this.currentState = this.localStorage.retrieve('code-button-state') || States.Password; if (this.useSsh) { this.useSshUrl(); } if (this.useToken) { this.useHttpsToken(); } if (this.usePassword) { this.useHttpsPassword(); } }Also applies to: 221-232
282-284
: Centralize error handling and improve error messages.Error handling is scattered and error messages could be more descriptive.
+private handleError(error: HttpErrorResponse, context: string) { + if (error.status === 403) { + this.alertService.warning(`artemisApp.exerciseActions.${context}.forbidden`); + } else if (error.status === 404) { + this.alertService.warning(`artemisApp.exerciseActions.${context}.notFound`); + } else { + this.alertService.error(`artemisApp.exerciseActions.${context}.error`); + } + throw error; +} loadParticipationVcsAccessToken(participation: ProgrammingExerciseStudentParticipation) { return this.accountService.getVcsAccessToken(participation.id).subscribe({ next: (res: HttpResponse<string>) => { if (res.body) { participation.vcsAccessToken = res.body; this.copyEnabled = this.useToken; } }, error: (error: HttpErrorResponse) => { if (error.status === 404) { this.createNewParticipationVcsAccessToken(participation); } - if (error.status == 403) { - this.alertService.warning('403 Forbidden'); - } + this.handleError(error, 'token'); }, }); }src/test/javascript/spec/component/shared/code-button.component.spec.ts (1)
148-158
: Improve test description and assertions.The test description could be more descriptive, and assertions could be more specific.
-it('should not load participation vcsAccessToken when it already exists in participation', async () => { +it('should skip loading vcsAccessToken from server when participation already has a valid token', async () => { participation.vcsAccessToken = 'vcpat-1234'; fixture.componentRef.setInput('participations', [participation]); await component.ngOnInit(); component.onClick(); - expect(component.user.vcsAccessToken).toEqual(vcsToken); + expect(component.user.vcsAccessToken).toBe(vcsToken); expect(getVcsAccessTokenSpy).not.toHaveBeenCalled(); expect(createVcsAccessTokenSpy).not.toHaveBeenCalled(); + expect(participation.vcsAccessToken).toBe('vcpat-1234'); });
📜 Review details
Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (4)
src/main/webapp/app/exam/participate/summary/exercises/programming-exam-summary/programming-exam-summary.component.html
(1 hunks)src/main/webapp/app/shared/components/code-button/code-button.component.html
(2 hunks)src/main/webapp/app/shared/components/code-button/code-button.component.ts
(9 hunks)src/test/javascript/spec/component/shared/code-button.component.spec.ts
(9 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
- src/main/webapp/app/exam/participate/summary/exercises/programming-exam-summary/programming-exam-summary.component.html
- src/main/webapp/app/shared/components/code-button/code-button.component.html
🧰 Additional context used
📓 Path-based instructions (2)
src/test/javascript/spec/component/shared/code-button.component.spec.ts (1)
Pattern src/test/javascript/spec/**/*.ts
: jest: true; mock: NgMocks; bad_practices: avoid_full_module_import; perf_improvements: mock_irrelevant_deps; service_testing: mock_http_for_logic; no_schema: avoid_NO_ERRORS_SCHEMA; expectation_specificity: true; solutions: {boolean: toBeTrue/False, reference: toBe, existence: toBeNull/NotNull, undefined: toBeUndefined, class_obj: toContainEntries/toEqual, spy_calls: {not_called: not.toHaveBeenCalled, once: toHaveBeenCalledOnce, with_value: toHaveBeenCalledWith|toHaveBeenCalledExactlyOnceWith}}
src/main/webapp/app/shared/components/code-button/code-button.component.ts (1)
📓 Learnings (1)
src/main/webapp/app/shared/components/code-button/code-button.component.ts (1)
Learnt from: SimonEntholzer
PR: ls1intum/Artemis#10147
File: src/main/webapp/app/shared/components/code-button/code-button.component.ts:1-1
Timestamp: 2025-01-18T08:49:30.693Z
Learning: In Angular 19+ projects, component inputs should use the new input() function from @angular/core instead of the @Input() decorator, as it's part of the new signals architecture that improves performance and type safety.
⏰ Context from checks skipped due to timeout of 90000ms (6)
- GitHub Check: server-tests
- GitHub Check: client-tests-selected
- GitHub Check: client-tests
- GitHub Check: Analyse
- GitHub Check: Build and Push Docker Image
- GitHub Check: Build .war artifact
🔇 Additional comments (2)
src/main/webapp/app/shared/components/code-button/code-button.component.ts (1)
241-254
: 🛠️ Refactor suggestionEnhance security of credential handling in URIs.
The current implementation exposes credentials in the URI. Consider using a more secure approach.
src/test/javascript/spec/component/shared/code-button.component.spec.ts (1)
184-186
: Use toHaveBeenCalledOnce for better test readability.Replace
toHaveBeenCalled
withtoHaveBeenCalledOnce
for better test readability.-expect(getVcsAccessTokenSpy).toHaveBeenCalled(); +expect(getVcsAccessTokenSpy).toHaveBeenCalledOnce();
src/main/webapp/app/shared/components/code-button/code-button.component.ts
Show resolved
Hide resolved
That's a good point, this would make sense now. I added it that students can now no longer access these settings via path. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Code. Thanks for implementing my suggestions!
0bd00f0
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
🧹 Nitpick comments (2)
src/test/java/de/tum/cit/aet/artemis/programming/icl/LocalVCInfoContributorTest.java (2)
16-21
: Enhance test method clarity and maintainability.
The test method name
testContribute
is too generic. Consider renaming it to describe the specific behavior being tested, e.g.,shouldContributeAuthenticationMechanismsToInfo
.Consider extracting the authentication mechanisms list as a constant or documenting why these specific values were chosen:
private static final List<String> EXPECTED_AUTHENTICATION_MECHANISMS = List.of("password", "token", "ssh");
- The use of reflection might indicate that
orderedAuthenticationMechanisms
should be passed through the constructor or a setter method instead.
29-29
: Enhance assertion specificity and error messages.The current assertion could be more robust. Consider:
assertThat(info.getDetails()) .as("Info details should not be null") .isNotNull() .containsKey("authenticationMechanisms"); assertThat(info.getDetails().get("authenticationMechanisms")) .as("Authentication mechanisms should match the configured values") .isNotNull() .isInstanceOf(List.class) .asList() .containsExactlyElementsOf(authenticationMechanisms);This provides:
- Null checks
- Type verification
- More descriptive error messages
- Exact list comparison
📜 Review details
Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
src/test/java/de/tum/cit/aet/artemis/programming/icl/LocalVCInfoContributorTest.java
(2 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
src/test/java/de/tum/cit/aet/artemis/programming/icl/LocalVCInfoContributorTest.java (1)
Pattern src/test/java/**/*.java
: test_naming: descriptive; test_size: small_specific; fixed_data: true; junit5_features: true; assert_use: assertThat; assert_specificity: true; archunit_use: enforce_package_rules; db_query_count_tests: track_performance; util_service_factory_pattern: true; avoid_db_access: true; mock_strategy: static_mocks; context_restart_minimize: true
⏰ Context from checks skipped due to timeout of 90000ms (9)
- GitHub Check: Codacy Static Code Analysis
- GitHub Check: server-tests
- GitHub Check: client-tests-selected
- GitHub Check: client-tests
- GitHub Check: client-style
- GitHub Check: server-style
- GitHub Check: Build and Push Docker Image
- GitHub Check: Build .war artifact
- GitHub Check: Analyse
🔇 Additional comments (1)
src/test/java/de/tum/cit/aet/artemis/programming/icl/LocalVCInfoContributorTest.java (1)
Line range hint
1-13
: LGTM! Clean imports and proper class structure.The imports are well-organized, and the test class follows proper naming conventions.
src/test/java/de/tum/cit/aet/artemis/programming/icl/LocalVCInfoContributorTest.java
Show resolved
Hide resolved
The API is still accessible for Instructors and Teaching Assistants, right? Because we rely on this API. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Code reapprove 👍
Checklist
General
Server
Client
Changes affecting Programming Exercises
Motivation and Context
The code-button code is quite complex and bug prone.
Description
Fixes #9972
Adds the following features:
['password', 'ssh', 'token']
. The code button will also show these mechanisms in that order.courses
andcourse-management
routes. Forcourse
routes, the code-button uses the participation token, as this is the students view. For the instructor view, it always uses the user token.Steps for Testing
Prerequisites:
Exam Mode Testing
Testserver States
Note
These badges show the state of the test servers.
Green = Currently available, Red = Currently locked
Click on the badges to get to the test servers.
Review Progress
Code Review
Manual Tests
Test Coverage
Screenshots
E.g. authentication set to
['ssh', 'token']
, so the password/https option is not available:Summary by CodeRabbit
Release Notes
Authentication
User Interface
Localization
Access Control
These changes enhance the authentication and repository access mechanisms, providing more flexible and streamlined user interactions.