Skip to content

Commit

Permalink
NAS-130332 / 25.04 / Fix remarks (#10439)
Browse files Browse the repository at this point in the history
* NAS-130332: Fix remarks

* NAS-130332: Rename SetTailLinesDialog to LogsDetailsDialog

* NAS-130332: Add unit tests

---------

Co-authored-by: Boris Vasilenko <[email protected]>
  • Loading branch information
bvasilenko and bvasilenko authored Aug 15, 2024
1 parent aff8262 commit 014b60d
Show file tree
Hide file tree
Showing 101 changed files with 295 additions and 333 deletions.
2 changes: 2 additions & 0 deletions src/app/pages/apps/apps.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ import { AppWorkloadsCardComponent } from 'app/pages/apps/components/installed-a
import { VolumeMountsDialogComponent } from 'app/pages/apps/components/installed-apps/app-workloads-card/volume-mounts-dialog/volume-mounts-dialog.component';
import { ContainerShellComponent } from 'app/pages/apps/components/installed-apps/container-shell/container-shell.component';
import { PodLogsComponent } from 'app/pages/apps/components/installed-apps/pod-logs/pod-logs.component';
import { LogsDetailsDialogComponent } from 'app/pages/apps/components/logs-details-dialog/logs-details-dialog.component';
import { SelectPoolDialogComponent } from 'app/pages/apps/components/select-pool-dialog/select-pool-dialog.component';
import { ShellDetailsDialogComponent } from 'app/pages/apps/components/shell-details-dialog/shell-details-dialog.component';
import { CustomFormsModule } from 'app/pages/apps/modules/custom-forms/custom-forms.module';
Expand Down Expand Up @@ -105,6 +106,7 @@ import { InstalledAppsComponent } from './components/installed-apps/installed-ap
AppAvailableInfoCardComponent,
ContainerShellComponent,
PodLogsComponent,
LogsDetailsDialogComponent,
ShellDetailsDialogComponent,
AppUpgradeDialogComponent,
AppDetailsHeaderComponent,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { HarnessLoader } from '@angular/cdk/testing';
import { TestbedHarnessEnvironment } from '@angular/cdk/testing/testbed';
import { MatButtonHarness } from '@angular/material/button/testing';
import { MatDialog } from '@angular/material/dialog';
import { Router } from '@angular/router';
import { Spectator } from '@ngneat/spectator';
import { createComponentFactory, mockProvider } from '@ngneat/spectator/jest';
import { MockComponent } from 'ng-mocks';
Expand All @@ -24,6 +25,7 @@ describe('AppContainersCardComponent', () => {
const app = {
id: 'ix-test-app',
name: 'ix-test-app',
metadata: { train: 'ix-test-train' },
upgrade_available: true,
state: CatalogAppState.Running,
active_workloads:
Expand Down Expand Up @@ -77,6 +79,7 @@ describe('AppContainersCardComponent', () => {
mockProvider(MatDialog, {
open: jest.fn(() => of(true)),
}),
mockProvider(Router),
mockAuth(),
],
});
Expand Down Expand Up @@ -144,10 +147,12 @@ describe('AppContainersCardComponent', () => {
);
});

it.skip('opens view logs dialog when View Logs button is pressed', async () => {
it('redirects to logs page when View Logs button is pressed', async () => {
const showLogsButton = await loader.getHarness(MatButtonHarness.with({ selector: '[aria-label="View Logs"]' }));
await showLogsButton.click();

expect(spectator.inject(MatDialog).open).toHaveBeenCalledWith(1);
expect(spectator.inject(Router).navigate).toHaveBeenCalledWith(
['/apps', 'installed', 'ix-test-train', 'ix-test-app', 'logs', '1'],
);
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -98,18 +98,4 @@ export class AppWorkloadsCardComponent {
formValue.command,
]);
}

private logDialogSubmit(formValue: ShellDetailsDialogFormValue): void {
const tailLines = (formValue.tail_lines).toString();
this.router.navigate([
'/apps',
'installed',
this.app().metadata.train,
this.app().name,
'logs',
// formValue.pods,
// formValue.containers,
tailLines,
]);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,11 @@
(valueChange)="onFontSizeChanged($event)"
></ix-toolbar-slider>

@if (false) {
<button mat-button ixTest="reconnect" (click)="reconnect()">
{{ 'Reconnect' | translate }}
</button>

<button mat-button ixTest="reconnect" (click)="reconnect()">
{{ 'Reconnect' | translate }}
</button>

@if (false) {
<button mat-button color="primary" ixTest="download-logs" (click)="onDownloadLogs()">
{{ 'Download Logs' | translate }}
</button>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
import { MatDialog, MatDialogRef } from '@angular/material/dialog';
import { ActivatedRoute } from '@angular/router';
import { Spectator, createComponentFactory, mockProvider } from '@ngneat/spectator/jest';
import { MockComponent, MockModule } from 'ng-mocks';
import { of } from 'rxjs';
import { mockAuth } from 'app/core/testing/utils/mock-auth.utils';
import { ToolbarSliderComponent } from 'app/modules/forms/toolbar-slider/toolbar-slider.component';
import { PageHeaderModule } from 'app/modules/page-header/page-header.module';
import { PodLogsComponent } from 'app/pages/apps/components/installed-apps/pod-logs/pod-logs.component';
import { LogsDetailsDialogComponent } from 'app/pages/apps/components/logs-details-dialog/logs-details-dialog.component';
import { WebSocketService } from 'app/services/ws.service';

describe('PodLogsComponent', () => {
let spectator: Spectator<PodLogsComponent>;

const createComponent = createComponentFactory({
component: PodLogsComponent,
imports: [
MockModule(PageHeaderModule),
],
declarations: [
MockComponent(ToolbarSliderComponent),
],
providers: [
mockProvider(MatDialog, {
open: jest.fn(() => ({
afterClosed: () => of({
tail_lines: 650,
} as LogsDetailsDialogComponent['form']['value']),
}) as unknown as MatDialogRef<LogsDetailsDialogComponent>),
}),
mockProvider(WebSocketService, {
subscribeToLogs: jest.fn(() => of({
fields: {
timestamp: '[12:34]',
data: 'Some logs.',
},
})),
}),
mockAuth(),
{
provide: ActivatedRoute,
useValue: {
parent: {
params: of({ appId: 'ix-test-app' }),
},
params: of({ containerId: 'ix-test-container' }),
},
},
],
});

beforeEach(() => {
spectator = createComponent();
});

it('subscribes to logs updates', () => {
expect(spectator.inject(MatDialog).open).toHaveBeenCalledWith(LogsDetailsDialogComponent, { width: '400px' });

expect(spectator.inject(WebSocketService).subscribeToLogs).toHaveBeenCalledWith(
'app.container_log_follow: {"app_name":"ix-test-app","container_id":"ix-test-container","tail_lines":650}',
);
});

it('shows meta data', () => {
expect(spectator.queryAll('.meta-data .name').map((name) => name.textContent.trim())).toEqual([
'ix-test-app',
'ix-test-container',
]);
});

it('shows logs', () => {
expect(spectator.queryAll('.log-row').map((name) => name.textContent.trim())).toEqual([
'[12:34]Some logs.',
]);
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,13 @@ import {
import { MatDialog } from '@angular/material/dialog';
import { ActivatedRoute } from '@angular/router';
import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy';
import { UUID } from 'angular2-uuid';
import { combineLatest, map, Subscription } from 'rxjs';
import {
combineLatest, map, Subscription, switchMap, tap,
} from 'rxjs';
import { WebSocketError } from 'app/interfaces/websocket-error.interface';
import { DialogService } from 'app/modules/dialog/dialog.service';
import { AppLoaderService } from 'app/modules/loader/app-loader.service';
import { LogsDetailsDialogComponent } from 'app/pages/apps/components/logs-details-dialog/logs-details-dialog.component';
import { DownloadService } from 'app/services/download.service';
import { ErrorHandlerService } from 'app/services/error-handler.service';
import { ShellService } from 'app/services/shell.service';
Expand All @@ -35,12 +37,12 @@ export class PodLogsComponent implements OnInit {
fontSize = 14;
appName: string;
containerId: string;
podLogSubscriptionId: string = null;
podLogSubName = '';
isLoadingPodLogs = false;
defaultTailLines = 500;

private podLogsChangedListener: Subscription;
podLogs: PodLogEvent[];
podLogs: PodLogEvent[] = [];

constructor(
private ws: WebSocketService,
Expand All @@ -66,16 +68,22 @@ export class PodLogsComponent implements OnInit {

// subscribe pod log for selected app, pod and container.
reconnect(): void {
this.podLogs = [];
this.isLoadingPodLogs = true;

if (this.podLogsChangedListener && !this.podLogsChangedListener.closed) {
this.podLogsChangedListener.unsubscribe();
}

this.podLogSubName = `app.container_log_follow:{"app_name": "${this.appName}", "container_id": "${this.containerId}"}`;
this.podLogSubscriptionId = UUID.UUID();
this.podLogsChangedListener = this.ws.subscribeToLogs(this.podLogSubName).pipe(
this.podLogsChangedListener = this.matDialog.open(LogsDetailsDialogComponent, { width: '400px' }).afterClosed().pipe(
tap((details: LogsDetailsDialogComponent['form']['value']) => {
this.podLogSubName = `app.container_log_follow: ${JSON.stringify({
app_name: this.appName,
container_id: this.containerId,
tail_lines: details.tail_lines || this.defaultTailLines,
})}`;

this.podLogs = [];
this.isLoadingPodLogs = true;
}),
switchMap(() => this.ws.subscribeToLogs(this.podLogSubName)),
map((apiEvent) => apiEvent.fields),
untilDestroyed(this),
).subscribe({
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<h1 mat-dialog-title>{{ 'Logs Details' | translate }}</h1>

<form class="ix-form-container" [formGroup]="form">
<ix-input
formControlName="tail_lines"
type="number"
[label]="'Tail Lines' | translate"
[required]="true"
></ix-input>

<div mat-dialog-actions align="end">
<button
mat-button
type="button"
matDialogClose
ixTest="cancel"
>
{{ 'Cancel' | translate }}
</button>
<button
mat-button
type="submit"
color="primary"
ixTest="choose"
[disabled]="form.invalid"
[matDialogClose]="this.form.value"
>
{{ 'Connect' | translate }}
</button>
</div>
</form>
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import { HarnessLoader } from '@angular/cdk/testing';
import { TestbedHarnessEnvironment } from '@angular/cdk/testing/testbed';
import { ReactiveFormsModule } from '@angular/forms';
import { MatButtonHarness } from '@angular/material/button/testing';
import { MatDialogRef } from '@angular/material/dialog';
import { createComponentFactory, mockProvider, Spectator } from '@ngneat/spectator/jest';
import { IxFormsModule } from 'app/modules/forms/ix-forms/ix-forms.module';
import { IxFormHarness } from 'app/modules/forms/ix-forms/testing/ix-form.harness';
import { LogsDetailsDialogComponent } from 'app/pages/apps/components/logs-details-dialog/logs-details-dialog.component';

describe('LogsDetailsDialogComponent', () => {
let loader: HarnessLoader;
let form: IxFormHarness;
let spectator: Spectator<LogsDetailsDialogComponent>;
const createComponent = createComponentFactory({
component: LogsDetailsDialogComponent,
imports: [
ReactiveFormsModule,
IxFormsModule,
],
providers: [
mockProvider(MatDialogRef),
],
});

beforeEach(async () => {
spectator = createComponent();
loader = TestbedHarnessEnvironment.loader(spectator.fixture);
form = await loader.getHarness(IxFormHarness);
});

it('dialog should be closed when Reconnect is pressed', async () => {
await form.fillForm({ 'Tail Lines': 600 });
const valueLogsForm = await form.getValues();

expect(valueLogsForm).toEqual({
'Tail Lines': '600',
});

const connectButton = await loader.getHarness(MatButtonHarness.with({ text: 'Connect' }));
await connectButton.click();
expect(spectator.inject(MatDialogRef).close).toHaveBeenCalledWith({
tail_lines: 600,
});
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import {
ChangeDetectionStrategy, Component,
} from '@angular/core';
import { FormBuilder, Validators } from '@angular/forms';
import { UntilDestroy } from '@ngneat/until-destroy';

@UntilDestroy()
@Component({
selector: 'ix-logs-details-dialog',
templateUrl: './logs-details-dialog.component.html',
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class LogsDetailsDialogComponent {
form = this.fb.group({
tail_lines: [500, [Validators.required]],
});

constructor(
private fb: FormBuilder,
) {}
}

This file was deleted.

Loading

0 comments on commit 014b60d

Please sign in to comment.