Skip to content

Commit

Permalink
Merge pull request #27 from onecx-apps/fixUnitTest
Browse files Browse the repository at this point in the history
Improve datepipe and fix unit tests
  • Loading branch information
mflamm authored May 23, 2024
2 parents dc71741 + aa12347 commit 08bdd95
Show file tree
Hide file tree
Showing 2 changed files with 102 additions and 49 deletions.
83 changes: 74 additions & 9 deletions src/app/shared/relative-date.pipe.spec.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,84 @@
// Core imports
import { TestBed } from '@angular/core/testing';
import { RelativeDatePipe } from './relative-date.pipe';
import { TranslateService } from '@ngx-translate/core';
import { TranslateServiceMock } from 'src/app/test/TranslateServiceMock';

describe('RelativeDatePipe', () => {
const value = [];
const pipe = new RelativeDatePipe(value as any);
let pipe: RelativeDatePipe;
let translateService: TranslateService;

beforeEach(async () => {
TestBed.configureTestingModule({
providers: [
RelativeDatePipe,
{ provide: TranslateService, useClass: TranslateServiceMock },
],
});

pipe = TestBed.inject(RelativeDatePipe);
translateService = TestBed.inject(TranslateService);
});

it('create an instance', () => {
expect(pipe).toBeTruthy();
});
it('should transform a string date to relative date', () => {
const result = pipe.transform('2022-07-01');
expect(result).toBe('1 year ago');

it('should transform date strings into relative time format', () => {
const now = new Date();
const fiveMinutesAgo = new Date(now.getTime() - 5 * 60 * 1000);
const result = pipe.transform(fiveMinutesAgo.toISOString());
expect(result).toBe('5 minutes ago');
});

it('should transform date objects into relative time format', () => {
const now = new Date();
const fiveMinutesAgo = new Date(now.getTime() - 5 * 60 * 1000);
const result = pipe.transform(fiveMinutesAgo);
expect(result).toBe('5 minutes ago');
});

it('should return "just now" for very recent dates', () => {
const now = new Date();
const justNow = new Date(now.getTime() - 1000); // 1 second ago
const result = pipe.transform(justNow);
expect(result).toBe('just now');
});
it('should return "just now" for durations under 60 seconds', () => {
const now = new Date();
const justNow = new Date(now.getTime() - 1000 * 59); // 59 second ago
const result = pipe.transform(justNow);
expect(result).toBe('just now');
});
it('should transform an object date to relative date', () => {
const date = new Date('2022-07-01');
const result = pipe.transform(date);
expect(result).toBe('1 year ago');

it('should handle dates in the past year correctly', () => {
const now = new Date();
const sixMonthsAgo = new Date(now.getTime() - 6 * 30 * 24 * 60 * 60 * 1000); // Approx 6 months
const result = pipe.transform(sixMonthsAgo);
expect(result).toBe('6 months ago');
});

it('should handle dates in the past years correctly', () => {
const now = new Date();
const twoYearsAgo = new Date(now.getTime() - 2 * 365 * 24 * 60 * 60 * 1000); // Approx 2 years
const result = pipe.transform(twoYearsAgo);
expect(result).toBe('2 years ago');
});

it('should return "1 hour ago" for exactly one hour ago', () => {
const now = new Date();
const oneHourAgo = new Date(now.getTime() - 60 * 60 * 1000); // 1 hour ago
const result = pipe.transform(oneHourAgo);
expect(result).toBe('1 hour ago');
});

it('should handle invalid input gracefully', () => {
const result = pipe.transform('invalid-date');
expect(result).toBeUndefined();
});

it('should handle invalid input gracefully', () => {
const result = pipe.transform(undefined);
expect(result).toBeUndefined();
});
});
68 changes: 28 additions & 40 deletions src/app/shared/relative-date.pipe.ts
Original file line number Diff line number Diff line change
@@ -1,51 +1,39 @@
// Core imports
import { Pipe, PipeTransform } from '@angular/core';

// Third party imports
import { TranslateService } from '@ngx-translate/core';
@Pipe({ name: 'relativeDate' })
export class RelativeDatePipe implements PipeTransform {
transform(value: Date | string | number | undefined): string | undefined {
if (value === undefined) {
return undefined;
}

const DIVISIONS: { amount: number; name: Intl.RelativeTimeFormatUnit }[] = [
{ amount: 60, name: 'seconds' },
{ amount: 60, name: 'minutes' },
{ amount: 24, name: 'hours' },
{ amount: 7, name: 'days' },
{ amount: 4.34524, name: 'weeks' },
{ amount: 12, name: 'months' },
{ amount: Number.POSITIVE_INFINITY, name: 'years' },
];
if (!(value instanceof Date)) {
value = new Date(value);
if (isNaN(value.getTime())) {
return undefined;
}
}

@Pipe({
name: 'relativeDate',
})
export class RelativeDatePipe implements PipeTransform {
rtf: Intl.RelativeTimeFormat;
const seconds = Math.floor((new Date().getTime() - value.getTime()) / 1000);

constructor(private readonly translateService: TranslateService) {
this.rtf = new Intl.RelativeTimeFormat(this.translateService.currentLang, {
style: 'long',
});
}
/** convert string format into relative date format */
transform(value: any, args?: any): any {
let date: Date;
switch (typeof value) {
case 'string':
date = new Date(value);
break;
case 'object':
date = value;
break;
default:
break;
if (seconds < 60) {
return 'just now';
}

let duration = (date.getTime() - new Date().getTime()) / 1000;
for (let i = 0; i <= DIVISIONS.length; i++) {
const division = DIVISIONS[i];
if (Math.abs(duration) < division.amount) {
return this.rtf.format(Math.round(duration), division.name);
const intervals = [
{ label: 'year', seconds: 31536000 },
{ label: 'month', seconds: 2592000 },
{ label: 'day', seconds: 86400 },
{ label: 'hour', seconds: 3600 },
{ label: 'minute', seconds: 60 },
{ label: 'second', seconds: 1 },
];

for (const interval of intervals) {
const count = Math.floor(seconds / interval.seconds);
if (count >= 1) {
return count + ` ${interval.label}${count !== 1 ? 's' : ''} ago`;
}
duration /= division.amount;
}
}
}

0 comments on commit 08bdd95

Please sign in to comment.