Skip to content

Commit

Permalink
Merge pull request #1208 from Patternslib/scrum-2726--i18ncache
Browse files Browse the repository at this point in the history
feat(pat-date-picker): Cache the ajax call to retrieve i18n picker translations.
  • Loading branch information
reinhardt authored Dec 13, 2024
2 parents fa870d1 + 9050ddc commit 70c08a3
Show file tree
Hide file tree
Showing 2 changed files with 97 additions and 42 deletions.
21 changes: 16 additions & 5 deletions src/pat/date-picker/date-picker.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import logging from "../../core/logging";
import Parser from "../../core/parser";
import dom from "../../core/dom";
import events from "../../core/events";
import store from "../../core/store";
import utils from "../../core/utils";

const log = logging.getLogger("date-picker");
Expand All @@ -30,6 +31,9 @@ parser.addAlias("behaviour", "behavior");
* "weekdaysShort": ["Sun","Mon","Tue","Wed","Thu","Fri","Sat"]
* } */

export const storage = store.session("pat-date-picker");


export default Base.extend({
name: "date-picker",
trigger: ".pat-date-picker",
Expand Down Expand Up @@ -184,11 +188,18 @@ export default Base.extend({
}

if (this.options.i18n) {
try {
const response = await fetch(this.options.i18n);
config.i18n = await response.json();
} catch {
log.error(`date-picker could not load i18n for ${this.options.i18n}`);
let i18n = storage.get(this.options.i18n);
if (!i18n) {
try {
const response = await fetch(this.options.i18n);
i18n = await response.json();
storage.set(this.options.i18n, i18n);
} catch {
log.error(`date-picker could not load i18n for ${this.options.i18n}`);
}
}
if (i18n) {
config.i18n = i18n;
}
}
this.pikaday = new Pikaday(config);
Expand Down
118 changes: 81 additions & 37 deletions src/pat/date-picker/date-picker.test.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import $ from "jquery";
import events from "../../core/events";
import { storage } from "./date-picker";
import pattern from "./date-picker";

Check warning on line 4 in src/pat/date-picker/date-picker.test.js

View workflow job for this annotation

GitHub Actions / test

'./date-picker' import is duplicated
import pattern_auto_submit from "../auto-submit/auto-submit";
import utils from "../../core/utils";
Expand Down Expand Up @@ -142,46 +143,89 @@ describe("pat-date-picker", function () {
});

describe("5 - Date picker with i18n", function () {
describe("with proper json URL", function () {
it("properly localizes the months and weekdays", async () => {
global.fetch = jest.fn().mockImplementation(mock_fetch_i18n);
document.body.innerHTML =
'<input type="date" class="pat-date-picker" value="2018-10-21" data-pat-date-picker="i18n:/path/to/i18njson" />';
const el = document.querySelector("input[type=date]");
pattern.init(el);
await utils.timeout(1); // wait a tick for async to settle.
const display_el = document.querySelector("time");
display_el.click();

const month = document.querySelector('.pika-lendar .pika-select-month option[selected="selected"]'); // prettier-ignore
expect(month.textContent).toBe("Oktober");

global.fetch.mockClear();
delete global.fetch;
});
it("with proper json URL properly localizes the months and weekdays", async () => {
global.fetch = jest.fn().mockImplementation(mock_fetch_i18n);
document.body.innerHTML =
'<input type="date" class="pat-date-picker" value="2018-10-21" data-pat-date-picker="i18n:/path/to/i18njson" />';
const el = document.querySelector("input[type=date]");
pattern.init(el);
await utils.timeout(1); // wait a tick for async to settle.
const display_el = document.querySelector("time");
display_el.click();

const month = document.querySelector('.pika-lendar .pika-select-month option[selected="selected"]'); // prettier-ignore
expect(month.textContent).toBe("Oktober");

// Clear the storage
storage.clear();
// Reset mock
global.fetch.mockClear();
delete global.fetch;
});

describe("with bogus json URL", function () {
it("falls back to default (english) month and weekday labels ", async () => {
// Simulate failing getJSON call
global.fetch = jest.fn().mockImplementation(() => {
throw "error";
});

document.body.innerHTML =
'<input type="date" class="pat-date-picker" value="2018-10-21" data-pat-date-picker="i18n:/path/to/i18njson" />';
const el = document.querySelector("input[type=date]");
pattern.init(el);
await utils.timeout(1); // wait a tick for async to settle.
const display_el = document.querySelector("time");
display_el.click();

const month = document.querySelector('.pika-lendar .pika-select-month option[selected="selected"]'); // prettier-ignore
expect(month.textContent).toBe("October");

global.fetch.mockClear();
delete global.fetch;
it("stores i18n results", async () => {
global.fetch = jest.fn().mockImplementation(mock_fetch_i18n);
document.body.innerHTML = `
<input
type="date"
class="pat-date-picker"
value="2018-10-21"
data-pat-date-picker="i18n:/path/to/i18njson"
/>
<input
type="date"
class="pat-date-picker"
value="2018-10-22"
data-pat-date-picker="i18n:/path/to/i18njson"
/>
`;
const els = document.querySelectorAll("input[type=date]");
pattern.init(els[0]);
await utils.timeout(1); // wait a tick for async to settle.
expect(global.fetch).toHaveBeenCalledTimes(1);

// Initializing the other pattern should not lead to another AJAX call.

// NOTE: in a real environment where multiple instances are
// initialized at once on the same page, before the ajax call has
// been completed, each instance will do an AJAX call. After that,
// when navigating to other pages with other date picker instance
// the cached value should be used and no more AJAX calls should be
// made.

pattern.init(els[1]);
await utils.timeout(1); // wait a tick for async to settle.
expect(global.fetch).toHaveBeenCalledTimes(1);

// Clear the storage
storage.clear();
// Reset mock
global.fetch.mockClear();
delete global.fetch;
});

it("with bogus json URL falls back to default (english) month and weekday labels ", async () => {
// Simulate failing getJSON call
global.fetch = jest.fn().mockImplementation(() => {
throw "error";
});

document.body.innerHTML =
'<input type="date" class="pat-date-picker" value="2018-10-21" data-pat-date-picker="i18n:/path/to/i18njson" />';
const el = document.querySelector("input[type=date]");
console.log(document.body.innerHTML);
pattern.init(el);
await utils.timeout(1); // wait a tick for async to settle.
console.log(document.body.innerHTML);
const display_el = document.querySelector("time");
display_el.click();

const month = document.querySelector('.pika-lendar .pika-select-month option[selected="selected"]'); // prettier-ignore
expect(month.textContent).toBe("October");

// Reset mock
global.fetch.mockClear();
delete global.fetch;
});
});

Expand Down

0 comments on commit 70c08a3

Please sign in to comment.