From d0e2f98f63661db45e0afa578661657febe1380b Mon Sep 17 00:00:00 2001 From: wakonig_k Date: Sat, 15 Feb 2025 17:44:50 +0100 Subject: [PATCH] tests: added tests for remote-data service --- .../src/app/core/model/scan-user-data.ts | 10 +- .../bec_atlas/src/app/core/model/session.ts | 2 +- .../src/app/core/remote-data.service.spec.ts | 220 +++++++++++++++++- .../src/app/core/remote-data.service.ts | 68 +++--- 4 files changed, 261 insertions(+), 39 deletions(-) diff --git a/frontend/bec_atlas/src/app/core/model/scan-user-data.ts b/frontend/bec_atlas/src/app/core/model/scan-user-data.ts index 273eec1..399e9be 100644 --- a/frontend/bec_atlas/src/app/core/model/scan-user-data.ts +++ b/frontend/bec_atlas/src/app/core/model/scan-user-data.ts @@ -1,7 +1,7 @@ export interface ScanUserData { - name: string; - user_rating: number; - system_rating: number; - user_comments: string; - system_comments: string; + name?: string; + user_rating?: number; + system_rating?: number; + user_comments?: string; + system_comments?: string; } diff --git a/frontend/bec_atlas/src/app/core/model/session.ts b/frontend/bec_atlas/src/app/core/model/session.ts index 73199a2..ce4ae1a 100644 --- a/frontend/bec_atlas/src/app/core/model/session.ts +++ b/frontend/bec_atlas/src/app/core/model/session.ts @@ -3,5 +3,5 @@ export interface Session { deployment_id?: string; _id: string; owner_groups?: string[]; - access_groups?: []; // This should probably be string[] as well + access_groups?: string[]; // This should probably be string[] as well } diff --git a/frontend/bec_atlas/src/app/core/remote-data.service.spec.ts b/frontend/bec_atlas/src/app/core/remote-data.service.spec.ts index 613bdd8..07fb193 100644 --- a/frontend/bec_atlas/src/app/core/remote-data.service.spec.ts +++ b/frontend/bec_atlas/src/app/core/remote-data.service.spec.ts @@ -1,16 +1,25 @@ import { TestBed } from '@angular/core/testing'; -import { RemoteDataService } from './remote-data.service'; +import { + RemoteDataService, + ScanDataService, + SessionDataService, +} from './remote-data.service'; import { provideHttpClient } from '@angular/common/http'; import { HttpTestingController, provideHttpClientTesting, } from '@angular/common/http/testing'; import { AppConfigService } from '../app-config.service'; +import { ScanDataResponse } from './model/scan-data'; +import { ScanUserData } from './model/scan-user-data'; describe('RemoteDataService', () => { let service: RemoteDataService; + let httpTesting: HttpTestingController; + let appConfigService: AppConfigService; + beforeEach(() => { TestBed.configureTestingModule({ providers: [ @@ -21,11 +30,216 @@ describe('RemoteDataService', () => { ], }); service = TestBed.inject(RemoteDataService); - const httpTesting = TestBed.inject(HttpTestingController); - const appConfigService = TestBed.inject(AppConfigService); + httpTesting = TestBed.inject(HttpTestingController); + appConfigService = TestBed.inject(AppConfigService); + }); + + afterEach(() => { + httpTesting.verify(); // Verify that no unmatched requests are outstanding }); it('should be created', () => { expect(service).toBeTruthy(); }); + + it('should get sessions with default parameters', async () => { + const mockSessions = [ + { + _id: '1', + name: 'Session 1', + owner_groups: ['group1'], + access_groups: ['group2'], + }, + { _id: '2', name: 'Session 2' }, + ]; + + const sessionService = TestBed.inject(SessionDataService); + const promise = sessionService.getSessions(); + + const req = httpTesting.expectOne((request) => + request.url.includes('sessions') + ); + expect(req.request.method).toBe('GET'); + expect(req.request.params.get('offset')).toBe('0'); + expect(req.request.params.get('limit')).toBe('100'); + + req.flush(mockSessions); + + const result = await promise; + expect(result).toEqual(mockSessions); + }); + + it('should get sessions with custom offset and limit', async () => { + const mockSessions = [ + { + _id: '1', + name: 'Session 1', + owner_groups: ['group1'], + access_groups: ['group2'], + }, + { _id: '2', name: 'Session 2' }, + ]; + + const sessionService = TestBed.inject(SessionDataService); + const promise = sessionService.getSessions(10, 5); + + const req = httpTesting.expectOne((request) => + request.url.includes('sessions') + ); + expect(req.request.method).toBe('GET'); + expect(req.request.params.get('offset')).toBe('10'); + expect(req.request.params.get('limit')).toBe('5'); + + req.flush(mockSessions); + + const result = await promise; + expect(result).toEqual(mockSessions); + }); + + it('should get scan data with default parameters', async () => { + const mockScanData: ScanDataResponse[] = [ + { + scan_id: '1', + scan_number: 1, + status: 'closed', + session_id: 'session1', + scan_name: 'Scan 1', + scan_type: 'step', + dataset_number: 1, + }, + { + scan_id: '2', + scan_number: 2, + status: 'open', + session_id: 'session1', + scan_name: 'Scan 2', + scan_type: 'fly', + dataset_number: 2, + }, + ]; + + const scanService = TestBed.inject(ScanDataService); + const promise = scanService.getScanData('session1'); + + const req = httpTesting.expectOne((request) => + request.url.includes('scans/session') + ); + expect(req.request.method).toBe('GET'); + expect(req.request.params.get('session_id')).toBe('session1'); + expect(req.request.params.get('offset')).toBe('0'); + expect(req.request.params.get('limit')).toBe('100'); + expect(req.request.params.get('fields')).toBe(''); + expect(req.request.params.get('sort')).toBe(''); + expect(req.request.params.get('includeUserData')).toBe('false'); + + req.flush(mockScanData); + + const result = await promise; + expect(result).toEqual(mockScanData); + }); + + it('should get scan data with custom parameters', async () => { + const mockScanData: ScanDataResponse[] = [ + { + scan_id: '1', + scan_number: 1, + status: 'closed', + session_id: 'session1', + scan_name: 'Scan 1', + scan_type: 'step', + dataset_number: 1, + user_metadata: { important: true }, + timestamp: 1234567890, + }, + ]; + + const scanService = TestBed.inject(ScanDataService); + const promise = scanService.getScanData( + 'session1', + 10, + 5, + ['field1', 'field2'], + true, + { timestamp: -1 } + ); + + const req = httpTesting.expectOne((request) => + request.url.includes('scans/session') + ); + expect(req.request.method).toBe('GET'); + expect(req.request.params.get('session_id')).toBe('session1'); + expect(req.request.params.get('offset')).toBe('10'); + expect(req.request.params.get('limit')).toBe('5'); + expect(req.request.params.getAll('fields')).toEqual(['field1', 'field2']); + expect(req.request.params.get('sort')).toBe('{"timestamp":-1}'); + expect(req.request.params.get('includeUserData')).toBe('true'); + + req.flush(mockScanData); + + const result = await promise; + expect(result).toEqual(mockScanData); + }); + + it('should get scan count with all parameters', async () => { + const mockResponse = { count: 42 }; + + const scanService = TestBed.inject(ScanDataService); + const promise = scanService.getScanCount('session1', 'scan1', 123); + + const req = httpTesting.expectOne((request) => + request.url.includes('scans/count') + ); + expect(req.request.method).toBe('GET'); + expect(req.request.params.get('session_id')).toBe('session1'); + expect(req.request.params.get('scan_name')).toBe('scan1'); + expect(req.request.params.get('dataset_number')).toBe('123'); + + req.flush(mockResponse); + + const result = await promise; + expect(result).toEqual(mockResponse); + }); + + it('should get scan count with no parameters', async () => { + const mockResponse = { count: 100 }; + + const scanService = TestBed.inject(ScanDataService); + const promise = scanService.getScanCount(); + + const req = httpTesting.expectOne((request) => + request.url.includes('scans/count') + ); + expect(req.request.method).toBe('GET'); + expect(req.request.params.get('session_id')).toBeNull(); + expect(req.request.params.get('scan_name')).toBeNull(); + expect(req.request.params.get('dataset_number')).toBeNull(); + + req.flush(mockResponse); + + const result = await promise; + expect(result).toEqual(mockResponse); + }); + + it('should update user data', async () => { + const mockResponse = 'success'; + const mockUserData: ScanUserData = { + name: 'Test Scan', + user_rating: 3, + system_rating: 0, + }; + + const scanService = TestBed.inject(ScanDataService); + const promise = scanService.updateUserData('scan1', mockUserData); + + const req = httpTesting.expectOne((request) => + request.url.includes('scans/user_data') + ); + expect(req.request.method).toBe('PATCH'); + expect(req.request.body).toEqual(mockUserData); + + req.flush(mockResponse); + + const result = await promise; + expect(result).toBe(mockResponse); + }); }); diff --git a/frontend/bec_atlas/src/app/core/remote-data.service.ts b/frontend/bec_atlas/src/app/core/remote-data.service.ts index 12ec768..0e2f952 100644 --- a/frontend/bec_atlas/src/app/core/remote-data.service.ts +++ b/frontend/bec_atlas/src/app/core/remote-data.service.ts @@ -1,4 +1,4 @@ -import { HttpClient, HttpHeaders } from '@angular/common/http'; +import { HttpClient, HttpHeaders, HttpParams } from '@angular/common/http'; import { Injectable } from '@angular/core'; import { firstValueFrom } from 'rxjs'; import { Session } from './model/session'; @@ -45,7 +45,7 @@ export class RemoteDataService { */ protected get( path: string, - params: { [key: string]: string | number | Array }, + params: { [key: string]: string | number | Array } | HttpParams, headers: HttpHeaders ) { return this.httpClient.get( @@ -165,21 +165,23 @@ export class ScanDataService extends RemoteDataService { fields: Array | null = null, includeUserData: boolean = false, sort: { [key: string]: number } | null = null - ) { + ): Promise> { let headers = new HttpHeaders(); headers = headers.set('Content-Type', 'application/json; charset=utf-8'); - return firstValueFrom(this.get>( - 'scans/session', - { - session_id: sessionId, - offset: offset.toString(), - limit: limit.toString(), - fields: fields ? fields : '', - sort: sort ? JSON.stringify(sort) : '', - includeUserData: includeUserData.toString(), - }, - headers - )); + return firstValueFrom( + this.get>( + 'scans/session', + { + session_id: sessionId, + offset: offset.toString(), + limit: limit.toString(), + fields: fields ? fields : '', + sort: sort ? JSON.stringify(sort) : '', + includeUserData: includeUserData.toString(), + }, + headers + ) + ); } /** * Method for getting the scan count @@ -195,7 +197,7 @@ export class ScanDataService extends RemoteDataService { sessionId: string | null = null, scanName: string | null = null, datasetNumber: number | null = null - ) { + ): Promise { let headers = new HttpHeaders(); let filters: { [key: string]: string | number } = {}; headers = headers.set('Content-Type', 'application/json; charset=utf-8'); @@ -208,7 +210,9 @@ export class ScanDataService extends RemoteDataService { if (datasetNumber !== null) { filters['dataset_number'] = datasetNumber; } - return firstValueFrom(this.get('scans/count', filters, headers)); + return firstValueFrom( + this.get('scans/count', filters, headers) + ); } /** @@ -219,16 +223,18 @@ export class ScanDataService extends RemoteDataService { * @throws HttpErrorResponse if the request fails * @throws TimeoutError if the request takes too long */ - updateUserData(scanId: string, userData: ScanUserData) { + updateUserData(scanId: string, userData: ScanUserData): Promise { let headers = new HttpHeaders(); headers = headers.set('Content-Type', 'application/json; charset=utf-8'); console.log('Updating user data', userData); - return firstValueFrom(this.patch( - 'scans/user_data', - { scan_id: scanId }, - userData, - headers - )); + return firstValueFrom( + this.patch( + 'scans/user_data', + { scan_id: scanId }, + userData, + headers + ) + ); } } @@ -244,13 +250,15 @@ export class SessionDataService extends RemoteDataService { * @throws HttpErrorResponse if the request fails * @throws TimeoutError if the request takes too long */ - getSessions(offset: number = 0, limit: number = 100) { + getSessions(offset: number = 0, limit: number = 100): Promise { let headers = new HttpHeaders(); headers = headers.set('Content-Type', 'application/json; charset=utf-8'); - return firstValueFrom(this.get( - 'sessions', - { offset: offset.toString(), limit: limit.toString() }, - headers - )); + return firstValueFrom( + this.get( + 'sessions', + { offset: offset.toString(), limit: limit.toString() }, + headers + ) + ); } }