Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion projects/components/src/link/link.component.scss
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,6 @@
.ht-link {
text-decoration-line: none;
text-decoration: none;
color: $gray-9;
color: inherit;
@include link-hover;
}
Original file line number Diff line number Diff line change
@@ -1,56 +1,87 @@
import { NavigationService } from '@hypertrace/common';
import { NavigationParamsType, NavigationService } from '@hypertrace/common';
import { createServiceFactory, mockProvider, SpectatorService } from '@ngneat/spectator/jest';
import { TracingNavigationService } from './tracing-navigation.service';

describe('Tracing Navigation Service', () => {
let spectator: SpectatorService<TracingNavigationService>;

const buildService = createServiceFactory({
service: TracingNavigationService
service: TracingNavigationService,
providers: [
mockProvider(NavigationService, {
navigate: jest.fn(),
isRelativePathActive: () => true
})
]
});

test('can navigate correctly to trace detail', () => {
spectator = buildService({
providers: [
mockProvider(NavigationService, {
navigateWithinApp: jest.fn(),
isRelativePathActive: () => true
})
]
});
spectator = buildService();
const navigationService = spectator.inject(NavigationService);
spectator.service.navigateToTraceDetail('trace-id', 'span-id', '1608150110610');
expect(navigationService.navigateWithinApp).toHaveBeenLastCalledWith([
'trace',
'trace-id',
{ spanId: 'span-id', startTime: '1608150110610' }
]);
expect(navigationService.navigate).toHaveBeenLastCalledWith({
navType: NavigationParamsType.InApp,
path: ['/trace', 'trace-id', { spanId: 'span-id', startTime: '1608150110610' }]
});

spectator.service.navigateToTraceDetail('trace-id', 'span-id');
expect(navigationService.navigateWithinApp).toHaveBeenLastCalledWith(['trace', 'trace-id', { spanId: 'span-id' }]);
expect(navigationService.navigate).toHaveBeenLastCalledWith({
navType: NavigationParamsType.InApp,
path: ['/trace', 'trace-id', { spanId: 'span-id' }]
});

spectator.service.navigateToTraceDetail('trace-id');
expect(navigationService.navigateWithinApp).toHaveBeenLastCalledWith(['trace', 'trace-id', {}]);
expect(navigationService.navigate).toHaveBeenLastCalledWith({
navType: NavigationParamsType.InApp,
path: ['/trace', 'trace-id', {}]
});
});

test('can navigate correctly to Api trace detail', () => {
spectator = buildService({
providers: [
mockProvider(NavigationService, {
navigateWithinApp: jest.fn(),
isRelativePathActive: () => true
})
]
test('builds correct trace detail navigation params', () => {
spectator = buildService();
expect(spectator.service.buildTraceDetailNavigationParam('trace-id', 'span-id', '1608150110610')).toEqual({
navType: NavigationParamsType.InApp,
path: ['/trace', 'trace-id', { spanId: 'span-id', startTime: '1608150110610' }]
});

expect(spectator.service.buildTraceDetailNavigationParam('trace-id', 'span-id')).toEqual({
navType: NavigationParamsType.InApp,
path: ['/trace', 'trace-id', { spanId: 'span-id' }]
});

expect(spectator.service.buildTraceDetailNavigationParam('trace-id')).toEqual({
navType: NavigationParamsType.InApp,
path: ['/trace', 'trace-id', {}]
});
});

test('builds correct Api trace detail navigation params', () => {
spectator = buildService();

expect(spectator.service.buildApiTraceDetailNavigationParam('trace-id', '1608150110610')).toEqual({
navType: NavigationParamsType.InApp,
path: ['/api-trace', 'trace-id', { startTime: '1608150110610' }]
});

expect(spectator.service.buildApiTraceDetailNavigationParam('trace-id')).toEqual({
navType: NavigationParamsType.InApp,
path: ['/api-trace', 'trace-id', {}]
});
});

test('can navigate correctly to Api trace detail', () => {
spectator = buildService();
const navigationService = spectator.inject(NavigationService);
spectator.service.navigateToApiTraceDetail('trace-id', '1608150110610');
expect(navigationService.navigateWithinApp).toHaveBeenLastCalledWith([
'api-trace',
'trace-id',
{ startTime: '1608150110610' }
]);
expect(navigationService.navigate).toHaveBeenLastCalledWith({
navType: NavigationParamsType.InApp,
path: ['/api-trace', 'trace-id', { startTime: '1608150110610' }]
});

spectator.service.navigateToApiTraceDetail('trace-id');
expect(navigationService.navigateWithinApp).toHaveBeenLastCalledWith(['api-trace', 'trace-id', {}]);
expect(navigationService.navigate).toHaveBeenLastCalledWith({
navType: NavigationParamsType.InApp,
path: ['/api-trace', 'trace-id', {}]
});
});
});
Original file line number Diff line number Diff line change
@@ -1,12 +1,20 @@
import { Injectable } from '@angular/core';
import { Dictionary, NavigationService } from '@hypertrace/common';
import { Dictionary, NavigationParams, NavigationParamsType, NavigationService } from '@hypertrace/common';
import { Observable } from 'rxjs';

@Injectable({ providedIn: 'root' })
export class TracingNavigationService {
public constructor(private readonly navigationService: NavigationService) {}

public navigateToTraceDetail(traceId: string, spanId?: string, startTime?: string | number): Observable<boolean> {
return this.navigationService.navigate(this.buildTraceDetailNavigationParam(traceId, spanId, startTime));
}

public buildTraceDetailNavigationParam(
traceId: string,
spanId?: string,
startTime?: string | number
): NavigationParams {
const optionalParams: Dictionary<string> = {};

if (startTime !== undefined) {
Expand All @@ -17,16 +25,26 @@ export class TracingNavigationService {
optionalParams.spanId = spanId;
}

return this.navigationService.navigateWithinApp(['trace', traceId, optionalParams]);
return {
navType: NavigationParamsType.InApp,
path: ['/trace', traceId, optionalParams]
};
}

public navigateToApiTraceDetail(traceId: string, startTime?: string | number): Observable<boolean> {
return this.navigationService.navigate(this.buildApiTraceDetailNavigationParam(traceId, startTime));
}

public buildApiTraceDetailNavigationParam(traceId: string, startTime?: string | number): NavigationParams {
const optionalParams: Dictionary<string> = {};

if (startTime !== undefined) {
optionalParams.startTime = `${String(startTime)}`;
}

return this.navigationService.navigateWithinApp(['api-trace', traceId, optionalParams]);
return {
navType: NavigationParamsType.InApp,
path: ['/api-trace', traceId, optionalParams]
};
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,26 +2,23 @@
@import 'font';

.ht-entity-renderer {
@include body-1-regular(currentColor);
display: flex;
flex-direction: row;
align-items: center;
font-weight: inherit;
color: $gray-9;
.name-with-icon {
display: flex;
flex-direction: row;
align-items: center;
font-weight: inherit;

.icon {
padding-right: 12px;
}
.icon {
padding-right: 12px;
}

.name {
@include ellipsis-overflow();
.name {
@include ellipsis-overflow();
}
}
}

.navigable {
@include link-hover();
}

.inherit-text-color {
@include body-1-regular(inherit);
.default-text-style {
color: $gray-9;
@include body-1-regular(currentColor);
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { IconType } from '@hypertrace/assets-library';
import { NavigationService } from '@hypertrace/common';
import { IconComponent } from '@hypertrace/components';
import { FormattingModule, NavigationParamsType, NavigationService } from '@hypertrace/common';
import { IconComponent, LinkComponent } from '@hypertrace/components';
import { createHostFactory, mockProvider, SpectatorHost } from '@ngneat/spectator/jest';
import { MockComponent } from 'ng-mocks';
import { entityIdKey, entityTypeKey, ObservabilityEntityType } from '../../graphql/model/schema/entity';
Expand All @@ -14,17 +14,21 @@ describe('Entity Renderer Component', () => {

const createHost = createHostFactory({
component: EntityRendererComponent,
imports: [FormattingModule],
providers: [
mockProvider(EntityNavigationService, {
navigateToEntity: jest.fn()
buildEntityDetailNavigationParams: jest.fn().mockReturnValue({
navType: NavigationParamsType.InApp,
path: ['/endpoint', 'test-id']
})
}),
mockProvider(NavigationService),
mockProvider(EntityIconLookupService, {
forEntity: jest.fn().mockReturnValue(ObservabilityIconType.Api)
})
],
shallow: true,
declarations: [MockComponent(IconComponent)]
declarations: [MockComponent(IconComponent), MockComponent(LinkComponent)]
});

test('renders a basic entity without navigation', () => {
Expand All @@ -49,12 +53,12 @@ describe('Entity Renderer Component', () => {
const entityNavService = spectator.inject(EntityNavigationService);
const rendererElement = spectator.query('.ht-entity-renderer')!;

expect(rendererElement).toExist();

expect(spectator.query('.name')).toHaveText('test api');
expect(spectator.query(IconComponent)!.icon).toBe(ObservabilityIconType.Api);

expect(rendererElement).not.toHaveClass('navigable');
spectator.dispatchFakeEvent(rendererElement, 'click');
expect(entityNavService.navigateToEntity).toHaveBeenCalledTimes(0);
expect(entityNavService.buildEntityDetailNavigationParams).not.toHaveBeenCalled();
});

test('renders a basic entity with navigation', () => {
Expand All @@ -75,15 +79,19 @@ describe('Entity Renderer Component', () => {
}
}
);
const entityNavService = spectator.inject(EntityNavigationService);
const rendererElement = spectator.query('.ht-entity-renderer')!;

expect(spectator.query('.name')).toHaveText('test api');
expect(spectator.query(IconComponent)!.icon).toBe(ObservabilityIconType.Api);

expect(rendererElement).toHaveClass('navigable');
spectator.dispatchFakeEvent(rendererElement, 'click');
expect(entityNavService.navigateToEntity).toHaveBeenCalledWith(entity, false);
expect(spectator.inject(EntityNavigationService).buildEntityDetailNavigationParams).toHaveBeenCalledWith(
entity,
false
);

expect(spectator.query(LinkComponent)?.paramsOrUrl).toEqual({
navType: NavigationParamsType.InApp,
path: ['/endpoint', 'test-id']
});
});

test('renders an entity without icon by default', () => {
Expand Down Expand Up @@ -143,23 +151,24 @@ describe('Entity Renderer Component', () => {
};

spectator = createHost(
`<ht-entity-renderer [entity]="entity" [inheritTextColor]="inheritTextColor">
`<ht-entity-renderer [entity]="entity" [inheritTextStyle]="inheritTextStyle">
</ht-entity-renderer>`,
{
hostProps: {
entity: entity,
inheritTextColor: false
inheritTextStyle: false
}
}
);

expect(spectator.query('.inherit-text-color')).not.toExist();
expect(spectator.query('.default-text-style')).toExist();
expect(spectator.query('.ht-entity-renderer')).toBe(spectator.query('.default-text-style'));

spectator.setHostInput({
inheritTextColor: true
inheritTextStyle: true
});
expect(spectator.query('.inherit-text-color')).toExist();
expect(spectator.query('.default-text-style')).not.toExist();

expect(spectator.query('.ht-entity-renderer')).toEqual(spectator.query('.inherit-text-color'));
expect(spectator.query('.ht-entity-renderer')).not.toBe(spectator.query('.default-text-style'));
});
});
Loading