Skip to content

Commit

Permalink
time component, stories and tests
Browse files Browse the repository at this point in the history
  • Loading branch information
tobi-or-not-tobi committed Dec 8, 2023
1 parent eeea7b6 commit 9c589d8
Show file tree
Hide file tree
Showing 9 changed files with 239 additions and 0 deletions.
1 change: 1 addition & 0 deletions libs/domain/site/src/components.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,4 @@ export * from '../navigation-item/navigation-item.def';
export * from '../notification-center/notification-center.def';
export * from '../price-mode-selector/price-mode-selector.def';
export * from '../price/price.def';
export * from '../time/time.def';
2 changes: 2 additions & 0 deletions libs/domain/site/time/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export * from './time.component';
export * from './time.model';
27 changes: 27 additions & 0 deletions libs/domain/site/time/stories/demo.stories.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { Meta, Story } from '@storybook/web-components';
import { TemplateResult, html } from 'lit';
import { storybookPrefix } from '../../.constants';
import { SiteTimeComponentAttributes } from '../time.model';

export default {
title: `${storybookPrefix}/time`,
args: {
stamp: new Date().toString(),
i18nToken: 'before-<time>-after',
},
argTypes: {
i18nToken: { control: { type: 'text' } },
},
parameters: { chromatic: { disableSnapshot: true } },
} as Meta;

const Template: Story<SiteTimeComponentAttributes> = (
props: SiteTimeComponentAttributes
): TemplateResult => {
return html`<oryx-site-time
.stamp=${props.stamp}
.i18nToken=${props.i18nToken}
></oryx-site-time>`;
};

export const Demo = Template.bind({});
31 changes: 31 additions & 0 deletions libs/domain/site/time/stories/static.stories.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { Meta, Story } from '@storybook/web-components';
import { TemplateResult, html } from 'lit';
import { storybookPrefix } from '../../.constants';
import { SiteTimeComponentAttributes } from '../time.model';

export default {
title: `${storybookPrefix}/time`,
} as Meta;

const Template: Story<SiteTimeComponentAttributes> = (
props: SiteTimeComponentAttributes
): TemplateResult => {
return html`<oryx-site-time
.stamp=${'Fri Dec 08 2023 16:52:54 GMT+0100'}
></oryx-site-time>
<oryx-site-time
.stamp=${'Fri Dec 08 2023 02:52:54 GMT+0100'}
></oryx-site-time>
<oryx-site-time
.stamp=${'Fri Dec 08 2023 08:52:54 GMT+0100'}
.i18nToken=${'before-<time>-after'}
></oryx-site-time>
<style>
oryx-site-time {
display: block;
}
</style> `;
};

export const Static = Template.bind({});
118 changes: 118 additions & 0 deletions libs/domain/site/time/time.component.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
import { fixture } from '@open-wc/testing-helpers';
import { createInjector, destroyInjector } from '@spryker-oryx/di';
import { LocaleService } from '@spryker-oryx/i18n';
import { siteProviders, siteTimeComponent } from '@spryker-oryx/site';
import { useComponent } from '@spryker-oryx/utilities';
import { html } from 'lit';
import { of } from 'rxjs';
import { SiteTimeComponent } from './time.component';

class MockLocaleService implements Partial<LocaleService> {
get = vi.fn().mockReturnValue(of('en'));
formatTime = vi.fn();
}

describe('SiteTimeComponent', () => {
let element: SiteTimeComponent;
let localeService: MockLocaleService;

beforeAll(async () => {
await useComponent([siteTimeComponent]);
});

beforeEach(async () => {
const injector = createInjector({
providers: [
...siteProviders,
{
provide: LocaleService,
useClass: MockLocaleService,
},
],
});

localeService = injector.inject(
LocaleService
) as unknown as MockLocaleService;
});

afterEach(() => {
destroyInjector();
vi.clearAllMocks();
});

describe('when the component is initialised', () => {
beforeEach(async () => {
element = await fixture(html`<oryx-site-time></oryx-site-time>`);
});

it('should be an instance of SiteDayComponent', () => {
expect(element).toBeInstanceOf(SiteTimeComponent);
});
});

describe('when the current locale is "en"', () => {
beforeEach(async () => {
localeService.get.mockReturnValue(of('en'));
});

describe('and the day is monday', () => {
beforeEach(async () => {
localeService.formatTime.mockReturnValue('formatted-time');
element = await fixture(
html`<oryx-site-time
.stamp=${'Fri Dec 08 2023 16:57:07'}
></oryx-site-time>`
);
});

it('should call the locale service to format the date', () => {
expect(localeService.formatTime).toHaveBeenCalledWith(
'Fri Dec 08 2023 16:57:07'
);
});

it('should render the formatted date', () => {
expect(element.shadowRoot?.textContent?.trim()).toBe('formatted-time');
});
});
});

describe('when an i18n token is provided', () => {
beforeEach(async () => {
localeService.get.mockReturnValue(of('en'));
localeService.formatTime.mockReturnValue('formatted-time');
});

describe('and there is a day available', () => {
beforeEach(async () => {
element = await fixture(
html`<oryx-site-time
.stamp=${'Fri Dec 08 2023 16:57:07'}
i18nToken="my.custom-<time>-time"
></oryx-site-time>`
);
});

it('should render the token', () => {
expect(element.shadowRoot?.textContent?.trim()).toBe(
'Custom formatted-time time'
);
});
});

describe('and there is no day available', () => {
beforeEach(async () => {
element = await fixture(
html`<oryx-site-time
i18nToken="my.custom-<time>-time"
></oryx-site-time>`
);
});

it('should not render the token', () => {
expect(element.shadowRoot?.textContent?.trim()).toBe('');
});
});
});
});
36 changes: 36 additions & 0 deletions libs/domain/site/time/time.component.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import { resolve } from '@spryker-oryx/di';
import { ContentMixin } from '@spryker-oryx/experience';
import { LocaleService } from '@spryker-oryx/i18n';
import {
computed,
hydrate,
signalAware,
signalProperty,
} from '@spryker-oryx/utilities';
import { LitElement, TemplateResult, html } from 'lit';
import { SiteTimeComponentAttributes } from './time.model';

@hydrate()
@signalAware()
export class SiteTimeComponent
extends ContentMixin(LitElement)
implements SiteTimeComponentAttributes
{
protected localeService = resolve(LocaleService);

@signalProperty() stamp?: string | number | Date;
@signalProperty() i18nToken?: string;

protected $time = computed(() =>
this.stamp ? this.localeService.formatTime(this.stamp) : undefined
);

protected override render(): TemplateResult | void {
if (!this.$time()) return;
if (this.i18nToken) {
return html`${this.i18n(this.i18nToken, { time: this.$time() })}`;
} else {
return html`${this.$time()}`;
}
}
}
6 changes: 6 additions & 0 deletions libs/domain/site/time/time.def.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { componentDef } from '@spryker-oryx/utilities';

export const siteTimeComponent = componentDef({
name: 'oryx-site-time',
impl: () => import('./time.component').then((m) => m.SiteTimeComponent),
});
17 changes: 17 additions & 0 deletions libs/domain/site/time/time.model.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
export interface SiteTimeComponentAttributes {
/**
* The value property represents the time in milliseconds.
*/
stamp?: number | string | Date;

/**
* The i18n token can be used to generate a time inside a text. The i18n token
* comes with a default token context parameter ("time"), which will generate the following
* i18n syntax:
*
* ```
* i18n('my.token-<time>', {date: '26-04-2023'})
* ```
*/
i18nToken?: string;
}
1 change: 1 addition & 0 deletions tsconfig.base.json
Original file line number Diff line number Diff line change
Expand Up @@ -279,6 +279,7 @@
"@spryker-oryx/site/price-mode-selector": [
"libs/domain/site/price-mode-selector/index.ts"
],
"@spryker-oryx/site/time": ["libs/domain/site/time/index.ts"],
"@spryker-oryx/themes": ["libs/template/themes/src/index.ts"],
"@spryker-oryx/themes/breakpoints": [
"libs/template/themes/breakpoints/index.ts"
Expand Down

0 comments on commit 9c589d8

Please sign in to comment.