-
Notifications
You must be signed in to change notification settings - Fork 1
LNK-4651: Add Adhoc Type for AdhocReportGeneration #1345
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
Merged
arianamihailescu
merged 10 commits into
dev
from
LNK-4651-AddHic-Type-for-AdhocReportGeneration
Jan 14, 2026
Merged
Changes from all commits
Commits
Show all changes
10 commits
Select commit
Hold shift + click to select a range
5d34f05
LNK-4651: Add Adhoc Type for AdhocReportGeneration
arianamihailescu 0cf2dfb
LNK-4651: Add AddHoc Type
arianamihailescu 700a410
Merge branch 'dev' into LNK-4651-AddHic-Type-for-AdhocReportGeneration
arianamihailescu 7158661
LNK-4651: AdHoc-Type-for AdhocReport
arianamihailescu 30ba9d4
Merge branch 'dev' of https://github.com/lantanagroup/link-cloud intoβ¦
arianamihailescu bbed52a
Merge remote-tracking branch 'origin/LNK-4651-AddHic-Type-for-AdhocReβ¦
arianamihailescu 002f862
Merge branch 'dev' into LNK-4651-AddHic-Type-for-AdhocReportGeneration
arianamihailescu 56d8424
LNK-4651: Add missing enum
arianamihailescu 98e3023
Merge remote-tracking branch 'origin/LNK-4651-AddHic-Type-for-AdhocReβ¦
arianamihailescu d288983
LNK-4651: AdHoc Type - enable/disable generate report button based onβ¦
arianamihailescu File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,14 @@ | ||
| ο»Ώusing LantanaGroup.Link.Shared.Application.Utilities; | ||
| using System.Text.Json.Serialization; | ||
|
|
||
| namespace LantanaGroup.Link.Shared.Application.Models; | ||
|
|
||
|
|
||
| [JsonConverter(typeof(JsonStringEnumConverter))] | ||
| public enum AdHocType | ||
| { | ||
| [StringValue("Manual")] | ||
| Manual = 0, | ||
| [StringValue("Automatic")] | ||
| Automatic = 1 | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
237 changes: 237 additions & 0 deletions
237
...dmin.UI/src/app/components/reports/generate-report/generate-report-form.component.spec.ts
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,237 @@ | ||
| import {ComponentFixture, TestBed, fakeAsync, tick, waitForAsync, flushMicrotasks} from '@angular/core/testing'; | ||
| import {GenerateReportFormComponent} from './generate-report-form.component'; | ||
| import {FormBuilder, ReactiveFormsModule} from '@angular/forms'; | ||
| import {async, of, throwError} from 'rxjs'; | ||
| import {MatSnackBar} from '@angular/material/snack-bar'; | ||
| import {TenantService} from '../../../services/gateway/tenant/tenant.service'; | ||
| import {MeasureDefinitionService} from '../../../services/gateway/measure-definition/measure.service'; | ||
| import {Router} from '@angular/router'; | ||
|
|
||
|
|
||
| import {MatDatepickerModule} from '@angular/material/datepicker'; | ||
| import {MatNativeDateModule} from '@angular/material/core'; | ||
|
|
||
|
|
||
| describe('GenerateReportFormComponent', () => { | ||
| let component: GenerateReportFormComponent; | ||
| let fixture: ComponentFixture<GenerateReportFormComponent>; | ||
| let tenantService: jasmine.SpyObj<TenantService>; | ||
| let measureDefinitionService: jasmine.SpyObj<MeasureDefinitionService>; | ||
| let snackBar: jasmine.SpyObj<MatSnackBar>; | ||
| let router: jasmine.SpyObj<Router>; | ||
|
|
||
| beforeEach(waitForAsync(() => { | ||
| // Create spies for services | ||
| tenantService = jasmine.createSpyObj('TenantService', ['autocompleteFacilities', 'getFacilityConfiguration', 'generateAdHocReport', 'checkFacility']); | ||
| measureDefinitionService = jasmine.createSpyObj('MeasureDefinitionService', ['getMeasureDefinitionConfigurations']); | ||
| snackBar = jasmine.createSpyObj('MatSnackBar', ['open']); | ||
| router = jasmine.createSpyObj('Router', ['navigate']); | ||
|
|
||
| // Mock service responses | ||
| tenantService.autocompleteFacilities.and.returnValue(of({facility1: 'Facility 1', facility2: 'Facility 2'})); | ||
|
|
||
| tenantService.generateAdHocReport.and.returnValue(of({reportId: 'mockReportId'})); | ||
| tenantService.checkFacility.and.returnValue(of(true)); | ||
|
|
||
|
|
||
| tenantService.getFacilityConfiguration.and.returnValue( | ||
| of({ | ||
| facilityId: 'facility1', | ||
| facilityName: 'Mock Facility', | ||
| timeZone: 'UTC', | ||
| scheduledReports: { | ||
| daily: ['Daily Report 1', 'Daily Report 2'], | ||
| monthly: ['Monthly Report 1'], | ||
| weekly: ['Weekly Report 1', 'Weekly Report 2'] | ||
| } | ||
| }) | ||
| ); | ||
|
|
||
|
|
||
| measureDefinitionService.getMeasureDefinitionConfigurations.and.returnValue( | ||
| of([{id: 'reportType1'}, {id: 'reportType2'}]) | ||
| ); | ||
|
|
||
| TestBed.configureTestingModule({ | ||
| imports: [ReactiveFormsModule, GenerateReportFormComponent, MatDatepickerModule, // Import for the datepicker | ||
| MatNativeDateModule // Import for the Native adapter | ||
| ], | ||
| declarations: [], | ||
| providers: [ | ||
| FormBuilder, | ||
| {provide: TenantService, useValue: tenantService}, | ||
| {provide: MeasureDefinitionService, useValue: measureDefinitionService}, | ||
| {provide: MatSnackBar, useValue: snackBar}, | ||
| {provide: Router, useValue: router} | ||
| ] | ||
| }).compileComponents(); | ||
| })); | ||
|
|
||
| beforeEach(() => { | ||
| fixture = TestBed.createComponent(GenerateReportFormComponent); | ||
| component = fixture.componentInstance; | ||
| fixture.detectChanges(); | ||
| }); | ||
|
|
||
| describe('Component Initialization', () => { | ||
| it('should create the component', () => { | ||
| expect(component).toBeTruthy(); | ||
| }); | ||
|
|
||
| it('should initialize the form with default values and controls', () => { | ||
| expect(component.generateReportForm.contains('facilityId')).toBeTrue(); | ||
| expect(component.generateReportForm.contains('startDate')).toBeTrue(); | ||
| expect(component.generateReportForm.contains('endDate')).toBeTrue(); | ||
| expect(component.generateReportForm.contains('reportTypes')).toBeTrue(); | ||
| expect(component.generateReportForm.contains('bypassSubmission')).toBeTrue(); | ||
| }); | ||
|
|
||
| it('should initialize reportTypes from MeasureDefinitionService', fakeAsync(() => { | ||
| tick(); | ||
| expect(component.reportTypes).toEqual(['reportType1', 'reportType2']); | ||
| })); | ||
|
|
||
| it('should initialize filteredFacilities as an observable', fakeAsync(() => { | ||
| component.facilityInputControl.setValue('Facility'); | ||
| tick(300); // Simulate debounce | ||
|
|
||
| component.filteredFacilities.subscribe(filtered => { | ||
| expect(filtered).toEqual([ | ||
| {facilityId: 'facility1', facilityName: 'Facility 1'}, | ||
| {facilityId: 'facility2', facilityName: 'Facility 2'} | ||
| ]); | ||
| }); | ||
| })); | ||
| }); | ||
|
|
||
| describe('Form Validation', () => { | ||
| it('should mark facilityId as required', () => { | ||
| const facilityIdControl = component.facilityIdControl; | ||
| facilityIdControl.setValue(''); | ||
| expect(facilityIdControl.valid).toBeFalse(); | ||
| expect(facilityIdControl.errors).toEqual({required: true}); | ||
|
|
||
| facilityIdControl.setValue('validFacility'); | ||
| expect(facilityIdControl.valid).toBeTrue(); | ||
| }); | ||
|
|
||
| it('should validate startDate and endDate', () => { | ||
| const startDateControl = component.startDateControl; | ||
| const endDateControl = component.endDateControl; | ||
|
|
||
| startDateControl.setValue(''); | ||
| expect(startDateControl.valid).toBeFalse(); | ||
|
|
||
| endDateControl.setValue(''); | ||
| expect(endDateControl.valid).toBeFalse(); | ||
|
|
||
| startDateControl.setValue(new Date()); | ||
| endDateControl.setValue(new Date()); | ||
| expect(startDateControl.valid).toBeTrue(); | ||
| expect(endDateControl.valid).toBeTrue(); | ||
| }); | ||
| }); | ||
|
|
||
| describe('Facility Input Handling', () => { | ||
| it('should handle facility input blur and validate facility', fakeAsync(() => { | ||
| component.facilities = [ | ||
| {facilityId: 'facility1', facilityName: 'Facility 1'}, | ||
| {facilityId: 'facility2', facilityName: 'Facility 2'} | ||
| ]; | ||
|
|
||
| tenantService.checkFacility.and.returnValue(of(false)); | ||
|
|
||
| component.facilityInputControl.setValue('Invalid Facility'); | ||
|
|
||
| component.onFacilityInputBlur(); | ||
| tick(200); // Allow time for the blur timeout | ||
|
|
||
| expect(component.facilityIdControl.errors).toEqual({notFound: true}); | ||
| expect(component.facilityIdControl.value).toEqual('Invalid Facility'); | ||
| })); | ||
|
|
||
| it('should handle facility selection', () => { | ||
| const facility = {facilityId: 'facility1', facilityName: 'Facility 1'}; | ||
| component.facilities = [facility]; // Mock the facilities | ||
|
|
||
| component.onFacilitySelected(facility); | ||
|
|
||
| expect(component.facilityIdControl.value).toBe(facility.facilityId); // Expect facilityId | ||
| expect(component.facilityInputControl.value).toBe(facility.facilityId); // Expect facilityId as well (matches the implementation) | ||
|
|
||
| }); | ||
| }); | ||
|
|
||
| describe('Form Submission', () => { | ||
| beforeEach(() => { | ||
| component.generateReportForm.patchValue({ | ||
| facilityId: 'facility1', | ||
| startDate: new Date(2023, 0, 1), | ||
| endDate: new Date(2023, 0, 31), | ||
| reportTypes: ['reportType1'], | ||
| bypassSubmission: false, | ||
| facilityInput: '', | ||
| patients: [], | ||
| selectedForm: 'manualPatients' | ||
| }); | ||
| }); | ||
|
|
||
| it('should submit the form successfully when valid', async () => { | ||
|
|
||
| const mockReportId = 'mockReportId'; | ||
|
|
||
| tenantService.generateAdHocReport.and.returnValue(of({reportId: 'mockReportId'})); | ||
|
|
||
| await component.generateReport(); | ||
| // tick(); | ||
|
|
||
| expect(component.lastGeneratedReport).toEqual({ | ||
| facilityId: 'facility1', | ||
| reportId: mockReportId | ||
| }); | ||
|
|
||
| expect(component.formSubmitted).toBeTrue(); | ||
| expect(tenantService.generateAdHocReport).toHaveBeenCalledWith( | ||
| 'facility1', | ||
| jasmine.objectContaining({ | ||
| reportTypes: ['reportType1'], | ||
| bypassSubmission: false | ||
| }) | ||
| ); | ||
| }); | ||
|
|
||
| it('should display an error when submission fails', fakeAsync(() => { | ||
|
|
||
| tenantService.generateAdHocReport.and.returnValue( | ||
| throwError(() => new Error('Failed to generate the report')) | ||
| ); | ||
|
|
||
| component.generateReport(); | ||
| flushMicrotasks(); | ||
| tick(); | ||
|
|
||
| //expect(component.errorMessage).toBe('Submission failed'); | ||
| expect(component.formSubmitted).toBeTrue(); | ||
|
|
||
| expect(tenantService.generateAdHocReport).toHaveBeenCalled(); | ||
|
|
||
| })); | ||
| }); | ||
|
|
||
| describe('Utility Functions', () => { | ||
| it('should reset the form correctly', () => { | ||
| component.generateReportForm.patchValue({ | ||
| facilityId: 'facility1', | ||
| startDate: new Date(), | ||
| endDate: new Date(), | ||
| reportTypes: ['type1'] | ||
| }); | ||
| (component as any).resetForm(); | ||
|
|
||
| expect(component.generateReportForm.get('facilityId')?.value).toBeNull(); | ||
| expect(component.generateReportForm.get('startDate')?.value).toBeNull(); | ||
| expect(component.generateReportForm.get('endDate')?.value).toBeNull(); | ||
| expect(component.generateReportForm.get('reportTypes')?.value).toBeNull(); | ||
| }); | ||
| }); | ||
| }); |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.