Skip to content

Commit b832099

Browse files
committed
refactor: instance creation
1 parent 91a0236 commit b832099

File tree

9 files changed

+139
-16
lines changed

9 files changed

+139
-16
lines changed

source/components/map/index.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
import MapFactory from './mapFactory';
1+
import MapFactory from './script/mapFactory';
2+
import type { MapArgs } from './script/mapInterface';
23

34
export function initializeMaps() {
45
document.querySelectorAll('[data-js-map]').forEach((mapContainer) => {
@@ -29,3 +30,5 @@ export function initializeMaps() {
2930
MapFactory.create(provider, args);
3031
});
3132
}
33+
34+
document.addEventListener('DOMContentLoaded', initializeMaps);

source/components/map/script/mapFactory.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
1+
import type { MapArgs, MapProviderFactory } from './mapInterface';
2+
13
class MapFactory {
2-
private static providers: Record<string, any> = {};
4+
private static providers: Record<string, MapProviderFactory> = {};
35

46
/**
57
* Creates a map instance for the specified provider using the provided arguments.
Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
type MapArgs = {
1+
export type MapArgs = {
22
container: HTMLElement;
33
id: string;
44
lat: string;
@@ -7,3 +7,7 @@ type MapArgs = {
77
style: string | null;
88
markers: string | null;
99
};
10+
11+
export interface MapProviderFactory {
12+
create(args: MapArgs): unknown;
13+
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
declare module '@helsingborg-stad/openstreetmap/dist/main.css?inline' {
2+
const content: string;
3+
export default content;
4+
}
Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
import Openstreetmap from './openstreetmap';
2+
import OpenstreetmapFactory from './openstreetmapFactory';
3+
4+
jest.mock('./openstreetmap', () => ({
5+
__esModule: true,
6+
default: jest.fn().mockImplementation((args) => ({
7+
args,
8+
})),
9+
}));
10+
11+
jest.mock('@helsingborg-stad/openstreetmap/dist/main.css?inline', () => ({
12+
__esModule: true,
13+
default: '/* mocked css */',
14+
}));
15+
16+
class FakeCSSStyleSheet {
17+
public replaceSync(_content: string): void {}
18+
}
19+
20+
const mockedOpenstreetmap = jest.mocked(Openstreetmap);
21+
22+
describe('OpenstreetmapFactory', () => {
23+
beforeEach(() => {
24+
jest.clearAllMocks();
25+
OpenstreetmapFactory.stylesLoaded = false;
26+
27+
document.body.innerHTML = '<div id="wrapper"><div id="map"></div></div>';
28+
Object.defineProperty(document, 'adoptedStyleSheets', {
29+
value: [],
30+
writable: true,
31+
configurable: true,
32+
});
33+
Object.defineProperty(globalThis, 'CSSStyleSheet', {
34+
value: FakeCSSStyleSheet,
35+
configurable: true,
36+
});
37+
});
38+
39+
it('passes normalized marker configs to the map implementation', () => {
40+
// Arrange
41+
const factory = new OpenstreetmapFactory();
42+
const container = document.querySelector('#wrapper') as HTMLElement;
43+
44+
// Act
45+
factory.create({
46+
container,
47+
id: 'map',
48+
lat: '56.0465',
49+
lng: '12.6945',
50+
style: 'dark',
51+
zoom: '12',
52+
markers: JSON.stringify([
53+
{ lat: '56.0465', lng: '12.6945', icon: 'pin_drop', content: 'Central square', color: '#123456' },
54+
{ lat: null, lng: '12.7' },
55+
]),
56+
});
57+
58+
// Assert
59+
expect(mockedOpenstreetmap).toHaveBeenCalledTimes(1);
60+
expect(mockedOpenstreetmap).toHaveBeenCalledWith({
61+
id: 'map',
62+
lat: 56.0465,
63+
lng: 12.6945,
64+
zoom: 12,
65+
style: 'dark',
66+
markers: [
67+
{
68+
lat: 56.0465,
69+
lng: 12.6945,
70+
icon: 'pin_drop',
71+
content: 'Central square',
72+
color: '#123456',
73+
},
74+
],
75+
});
76+
expect(document.adoptedStyleSheets).toHaveLength(1);
77+
});
78+
79+
it('falls back to the default zoom for invalid zoom values', () => {
80+
// Arrange
81+
const factory = new OpenstreetmapFactory();
82+
const container = document.querySelector('#wrapper') as HTMLElement;
83+
84+
// Act
85+
factory.create({
86+
container,
87+
id: 'map',
88+
lat: '56.0465',
89+
lng: '12.6945',
90+
style: null,
91+
zoom: 'not-a-number',
92+
markers: null,
93+
});
94+
95+
// Assert
96+
expect(mockedOpenstreetmap).toHaveBeenCalledWith(
97+
expect.objectContaining({
98+
zoom: 16,
99+
style: 'default',
100+
markers: [],
101+
}),
102+
);
103+
});
104+
});

source/components/map/script/providers/openstreetmap/openstreetmapFactory.ts

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
1-
import { LatLngObject, type MapStyle, MarkerOptions, TooltipOptions } from '@helsingborg-stad/openstreetmap';
1+
import type { MapStyle } from '@helsingborg-stad/openstreetmap';
22
import sheet from '@helsingborg-stad/openstreetmap/dist/main.css?inline';
3+
import type { MapArgs } from '../../mapInterface';
34
import Openstreetmap from './openstreetmap';
45
import type { MarkerConfig, OpenstreetmapArgs } from './openstreetmapInterface';
56

@@ -50,7 +51,7 @@ class OpenstreetmapFactory {
5051
lng: Number(args.lng),
5152
zoom,
5253
style,
53-
markers: markers,
54+
markers,
5455
};
5556

5657
return verifiedArgs;
@@ -71,15 +72,19 @@ class OpenstreetmapFactory {
7172

7273
const markerConfigs: MarkerConfig[] = [];
7374
for (const marker of markers) {
74-
if (!marker.lat || isNaN(Number(marker.lat)) || !marker.lng || isNaN(Number(marker.lng))) {
75+
const lat = Number(marker.lat);
76+
const lng = Number(marker.lng);
77+
78+
if (marker.lat == null || Number.isNaN(lat) || marker.lng == null || Number.isNaN(lng)) {
7579
continue;
7680
}
7781

7882
markerConfigs.push({
79-
lat: Number(marker.lat),
80-
lng: Number(marker.lng),
83+
lat,
84+
lng,
8185
icon: marker.icon || null,
8286
content: marker.content || null,
87+
color: marker.color || null,
8388
});
8489
}
8590

@@ -111,7 +116,9 @@ class OpenstreetmapFactory {
111116
* @returns A numeric zoom level.
112117
*/
113118
private getZoom(zoom: string | null): number {
114-
return isNaN(Number(zoom)) ? 16 : Number(zoom);
119+
const parsedZoom = Number(zoom);
120+
121+
return Number.isNaN(parsedZoom) ? 16 : parsedZoom;
115122
}
116123

117124
/**
Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,22 @@
1-
import { LatLngObject, type MapStyle, type MarkerOptions, TooltipOptions } from '@helsingborg-stad/openstreetmap';
1+
import type { MapStyle } from '@helsingborg-stad/openstreetmap';
22

3-
type OpenstreetmapArgs = {
3+
export type OpenstreetmapArgs = {
44
id: string;
55
lat: number;
66
lng: number;
77
zoom: number;
88
style: MapStyle;
9-
markers: Array<MarkerOptions>;
9+
markers: MarkerConfig[];
1010
};
1111

12-
type MarkerConfig = {
12+
export type MarkerConfig = {
1313
lat: number;
1414
lng: number;
1515
icon?: string;
1616
content?: string;
1717
color?: string;
1818
};
1919

20-
interface CreateMarker {
20+
export interface CreateMarker {
2121
create(markerConfig: MarkerConfig): void;
2222
}

source/js/app.js

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,6 @@ import { moveElements } from './helpers/moveElements';
4141
import { initializeIframeAcceptance } from './iframeAcceptance';
4242
import { initializeMegaMenus } from './megaMenu';
4343
import { initializeModal } from './modal';
44-
import { initializeOpenStreetMaps } from './openStreetMap';
4544
import { initializeResizeMediaQuery } from './resizeMediaQuery';
4645
import { SimulateClick } from './SimulateClick';
4746
import { initializeSegments } from './segment';
@@ -93,7 +92,6 @@ document.addEventListener('DOMContentLoaded', () => {
9392

9493
// Functions
9594
initializeResizeMediaQuery();
96-
initializeOpenStreetMaps();
9795
initializeDrawerAccessibility();
9896
initializeForms();
9997
initializeSlider();

source/js/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,3 +17,4 @@ export * from '../components/slider/slider';
1717
export * from '../components/table/table.js';
1818
export * from '../components/testimonials/testimonials.js';
1919
export * from '../components/tooltip/tooltip.js';
20+
export * from '../components/map/index.js';

0 commit comments

Comments
 (0)