Skip to content

Commit 82fc012

Browse files
committed
test: add locale/includeFallback coverage for taxonomy, term, and term-query
Add mock fixtures and unit/API test cases exercising locale-based fetch and query behavior across Taxonomy, Term, and TermQuery.
1 parent 8121f6a commit 82fc012

7 files changed

Lines changed: 268 additions & 6 deletions

File tree

‎test/api/taxonomy.spec.ts‎

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ dotenv.config()
1010
const countryUsa = process.env.TAX_COUNTRY_USA || 'usa'
1111
const locale = process.env.TAX_LOCALE || 'en-us'
1212
const stack = stackInstance();
13-
describe('ContentType API test cases', () => {
13+
describe('Taxonomy API test cases', () => {
1414
it('should give taxonomies when taxonomies method is called', async () => {
1515
const result = await makeTaxonomies().find<TTaxonomies>();
1616
expect(result).toBeDefined();
@@ -33,6 +33,34 @@ describe('ContentType API test cases', () => {
3333
const result = await makeTaxonomy(countryUsa).includeFallback().fetch<TTaxonomy>(locale);
3434
expect(result).toBeDefined();
3535
});
36+
37+
it('should give a localized taxonomy when fetch is called with locale', async () => {
38+
const result = await makeTaxonomy('taxonomy_testing').fetch<TTaxonomy>('fr-fr');
39+
expect(result).toBeDefined();
40+
});
41+
});
42+
43+
describe('Taxonomy API test cases - gadgets', () => {
44+
it('should fetch gadgets taxonomy in en-us (master locale)', async () => {
45+
const result = await makeTaxonomy('gadgets').fetch<TTaxonomy>();
46+
expect(result).toBeDefined();
47+
expect(result.uid).toBe('gadgets');
48+
});
49+
50+
it('should fetch gadgets taxonomy in fr-fr locale', async () => {
51+
const result = await makeTaxonomy('gadgets').fetch<TTaxonomy>('fr-fr');
52+
expect(result).toBeDefined();
53+
expect(result.uid).toBe('gadgets');
54+
expect(result.locale).toBe('fr-fr');
55+
});
56+
57+
it('should return gadgets in the taxonomies list', async () => {
58+
const result = await makeTaxonomies().find<TTaxonomies>();
59+
expect(result).toBeDefined();
60+
expect(result.taxonomies).toBeDefined();
61+
const gadgets = result.taxonomies.find((t: any) => t.uid === 'gadgets');
62+
expect(gadgets).toBeDefined();
63+
});
3664
});
3765

3866
function makeTaxonomies(): TaxonomyQuery {

‎test/api/term-query.spec.ts‎

Lines changed: 87 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ const stack = stackInstance();
88
const countryUsa = process.env.TAX_COUNTRY_USA || 'usa'
99
const locale = process.env.TAX_LOCALE || 'en-us'
1010

11-
describe("Terms API test cases", () => {
11+
describe("Terms Query API test cases", () => {
1212
it("should check for terms is defined", async () => {
1313
const result = await makeTerms(countryUsa).find<TTerm>();
1414
if (result.terms) {
@@ -38,9 +38,94 @@ describe("Terms API test cases", () => {
3838
expect(result.terms).toBeDefined();
3939
}
4040
});
41+
42+
it("should return terms for given locale when locale() is chained", async () => {
43+
const result = await makeTerms("taxonomy_testing").locale("hi-in").find<TTerm>();
44+
expect(result).toBeDefined();
45+
});
46+
47+
it("should return terms with fallback when includeFallback() is chained", async () => {
48+
const result = await makeTerms("taxonomy_testing").includeFallback().find<TTerm>();
49+
expect(result).toBeDefined();
50+
});
51+
52+
it("should return localized terms with fallback when locale() and includeFallback() are chained", async () => {
53+
const result = await makeTerms("taxonomy_testing").locale("hi-in").includeFallback().find<TTerm>();
54+
expect(result).toBeDefined();
55+
});
4156
});
57+
4258
function makeTerms(taxonomyUid = ""): TermQuery {
4359
const terms = stack.taxonomy(taxonomyUid).term();
44-
4560
return terms;
4661
}
62+
63+
describe("Term Query API test cases - gadgets taxonomy", () => {
64+
// Case 1: locale=en-us, include_fallback=false
65+
// Returns 5 terms: tablet, laptop, smartwatch, smartphone, headphone — all en-us
66+
it("should return all 5 en-us terms when locale is en-us and includeFallback is not set", async () => {
67+
const result = await stack.taxonomy("gadgets").term().locale("en-us").find<TTerm>();
68+
expect(result).toBeDefined();
69+
expect(result.terms).toBeDefined();
70+
expect(result.terms.length).toBe(5);
71+
const byUid = Object.fromEntries(result.terms.map((t: any) => [t.uid, t]));
72+
expect(byUid["tablet"].name).toBe("Tablet");
73+
expect(byUid["laptop"].name).toBe("Laptop");
74+
expect(byUid["smartwatch"].name).toBe("Smartwatch");
75+
expect(byUid["smartphone"].name).toBe("Smartphone");
76+
expect(byUid["headphone"].name).toBe("Headphone");
77+
result.terms.forEach((t: any) => expect(t.locale).toBe("en-us"));
78+
});
79+
80+
// Case 2: locale=en-us, include_fallback=true
81+
// Returns same 5 terms — all en-us (no change since en-us is master)
82+
it("should return all 5 en-us terms when locale is en-us and includeFallback is true", async () => {
83+
const result = await stack.taxonomy("gadgets").term().locale("en-us").includeFallback().find<TTerm>();
84+
expect(result).toBeDefined();
85+
expect(result.terms).toBeDefined();
86+
expect(result.terms.length).toBe(5);
87+
const byUid = Object.fromEntries(result.terms.map((t: any) => [t.uid, t]));
88+
expect(byUid["tablet"].name).toBe("Tablet");
89+
expect(byUid["laptop"].name).toBe("Laptop");
90+
expect(byUid["smartwatch"].name).toBe("Smartwatch");
91+
expect(byUid["smartphone"].name).toBe("Smartphone");
92+
expect(byUid["headphone"].name).toBe("Headphone");
93+
result.terms.forEach((t: any) => expect(t.locale).toBe("en-us"));
94+
});
95+
96+
// Case 3: locale=fr-fr, include_fallback=false
97+
// Returns 3 fr-fr terms only — tablet and laptop have no fr-fr translation so they are excluded
98+
it("should return only 3 fr-fr localized terms when locale is fr-fr and includeFallback is false", async () => {
99+
const result = await stack.taxonomy("gadgets").term().locale("fr-fr").find<TTerm>();
100+
expect(result).toBeDefined();
101+
expect(result.terms).toBeDefined();
102+
expect(result.terms.length).toBe(3);
103+
const byUid = Object.fromEntries(result.terms.map((t: any) => [t.uid, t]));
104+
expect(byUid["headphone"].name).toBe("Headphone-fr");
105+
expect(byUid["smartphone"].name).toBe("Smartphone-fr");
106+
expect(byUid["smartwatch"].name).toBe("Smartwatch-fr");
107+
expect(byUid["tablet"]).toBeUndefined();
108+
expect(byUid["laptop"]).toBeUndefined();
109+
result.terms.forEach((t: any) => expect(t.locale).toBe("fr-fr"));
110+
});
111+
112+
// Case 4: locale=fr-fr, include_fallback=true
113+
// Returns 5 terms: 3 in fr-fr + 2 fallback to en-us (tablet, laptop)
114+
it("should return 5 terms with fr-fr terms and en-us fallback when locale is fr-fr and includeFallback is true", async () => {
115+
const result = await stack.taxonomy("gadgets").term().locale("fr-fr").includeFallback().find<TTerm>();
116+
expect(result).toBeDefined();
117+
expect(result.terms).toBeDefined();
118+
expect(result.terms.length).toBe(5);
119+
const byUid = Object.fromEntries(result.terms.map((t: any) => [t.uid, t]));
120+
expect(byUid["headphone"].name).toBe("Headphone-fr");
121+
expect(byUid["headphone"].locale).toBe("fr-fr");
122+
expect(byUid["smartphone"].name).toBe("Smartphone-fr");
123+
expect(byUid["smartphone"].locale).toBe("fr-fr");
124+
expect(byUid["smartwatch"].name).toBe("Smartwatch-fr");
125+
expect(byUid["smartwatch"].locale).toBe("fr-fr");
126+
expect(byUid["tablet"].name).toBe("Tablet");
127+
expect(byUid["tablet"].locale).toBe("en-us");
128+
expect(byUid["laptop"].name).toBe("Laptop");
129+
expect(byUid["laptop"].locale).toBe("en-us");
130+
});
131+
});

‎test/api/term.spec.ts‎

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,11 @@ describe("Terms API test cases", () => {
3131
expect(result).toBeDefined();
3232
});
3333

34+
it("should get a localized term when fetch is called with locale", async () => {
35+
const result = await stack.taxonomy("taxonomy_testing").term("vehicles").fetch<TTerm>("fr-fr");
36+
expect(result).toBeDefined();
37+
});
38+
3439
it("should get locales for a term", async () => {
3540
const result = await makeTerms("texas").locales<TTerms>();
3641
expect(result).toBeDefined();
@@ -57,3 +62,44 @@ function makeTerms(termUid = ""): Term {
5762
const terms = stack.taxonomy(countryUsa).term(termUid);
5863
return terms;
5964
}
65+
66+
describe("Terms API test cases - gadgets taxonomy", () => {
67+
it("should fetch a term from gadgets taxonomy", async () => {
68+
const result = await stack.taxonomy("gadgets").term("smartphone").fetch<TTerm>();
69+
expect(result).toBeDefined();
70+
expect(result.uid).toBe("smartphone");
71+
expect(result.taxonomy_uid).toBe("gadgets");
72+
});
73+
74+
it("should fetch smartphone term from gadgets in fr-fr locale", async () => {
75+
const result = await stack.taxonomy("gadgets").term("smartphone").fetch<TTerm>("fr-fr");
76+
expect(result).toBeDefined();
77+
expect(result.uid).toBe("smartphone");
78+
expect(result.locale).toBe("fr-fr");
79+
expect((result as any).name).toBe("Smartphone-fr");
80+
});
81+
82+
it("should fetch all locales for a gadgets term", async () => {
83+
const result = await stack.taxonomy("gadgets").term("smartphone").locales<TTerms>();
84+
expect(result).toBeDefined();
85+
expect(result.terms).toBeDefined();
86+
expect(result.terms.length).toBeGreaterThan(0);
87+
const locales = result.terms.map((t: any) => t.locale);
88+
expect(locales).toContain("en-us");
89+
expect(locales).toContain("hi-in");
90+
});
91+
92+
it("should return empty ancestors for a root-level term in gadgets", async () => {
93+
const result = await stack.taxonomy("gadgets").term("smartphone").ancestors<TTerms>();
94+
expect(result).toBeDefined();
95+
expect(result.terms).toBeDefined();
96+
expect(result.terms.length).toBe(0);
97+
});
98+
99+
it("should return empty descendants for a leaf term in gadgets", async () => {
100+
const result = await stack.taxonomy("gadgets").term("smartphone").descendants<TTerms>();
101+
expect(result).toBeDefined();
102+
expect(result.terms).toBeDefined();
103+
expect(result.terms.length).toBe(0);
104+
});
105+
});

‎test/unit/taxonomy.spec.ts‎

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { TaxonomyQuery } from '../../src/query/taxonomy-query';
22
import { Taxonomy } from '../../src/taxonomy';
33
import { AxiosInstance, httpClient } from '@contentstack/core';
44
import MockAdapter from 'axios-mock-adapter';
5-
import { taxonomyFindResponseDataMock } from '../utils/mocks';
5+
import { taxonomyFindResponseDataMock, taxonomyLocalizedFetchMock } from '../utils/mocks';
66
import { MOCK_CLIENT_OPTIONS } from '../utils/constant';
77
import { Term } from '../../src/taxonomy/term';
88
import { TermQuery } from '../../src/query/term-query';
@@ -53,4 +53,10 @@ describe('ta class', () => {
5353

5454
await taxonomy.includeFallback().includeBranch().param('locale', 'fr-fr').fetch();
5555
});
56+
57+
it('should return localized taxonomy when fetch is called with locale', async () => {
58+
mockClient.onGet('/taxonomies/taxonomy_testing').reply(200, taxonomyLocalizedFetchMock);
59+
const response = await taxonomy.fetch('hi-in');
60+
expect(response).toEqual(taxonomyLocalizedFetchMock.taxonomy);
61+
});
5662
});

‎test/unit/term-query.spec.ts‎

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { TermQuery } from '../../src/query/term-query';
22
import { AxiosInstance, httpClient } from '@contentstack/core';
33
import MockAdapter from 'axios-mock-adapter';
4-
import { termQueryFindResponseDataMock } from '../utils/mocks';
4+
import { termQueryFindResponseDataMock, termQueryLocalizedFindMock } from '../utils/mocks';
55
import { MOCK_CLIENT_OPTIONS } from '../utils/constant';
66

77
describe('TermQuery class', () => {
@@ -55,4 +55,26 @@ describe('TermQuery class', () => {
5555

5656
await termQuery.param('locale', 'fr-fr').addParams({ order: 1 }).find();
5757
});
58+
59+
it('should set locale query param when locale() is called', async () => {
60+
mockClient.onGet('/taxonomies/taxonomy_testing/terms').reply(200, termQueryLocalizedFindMock);
61+
const response = await termQuery.locale('hi-in').find();
62+
expect(termQuery._queryParams.locale).toBe('hi-in');
63+
expect(response).toEqual(termQueryLocalizedFindMock);
64+
});
65+
66+
it('should set include_fallback query param when includeFallback() is called', async () => {
67+
mockClient.onGet('/taxonomies/taxonomy_testing/terms').reply(200, termQueryFindResponseDataMock);
68+
const response = await termQuery.includeFallback().find();
69+
expect(termQuery._queryParams.include_fallback).toBe('true');
70+
expect(response).toEqual(termQueryFindResponseDataMock);
71+
});
72+
73+
it('should set both locale and include_fallback when chained', async () => {
74+
mockClient.onGet('/taxonomies/taxonomy_testing/terms').reply(200, termQueryLocalizedFindMock);
75+
const response = await termQuery.locale('hi-in').includeFallback().find();
76+
expect(termQuery._queryParams.locale).toBe('hi-in');
77+
expect(termQuery._queryParams.include_fallback).toBe('true');
78+
expect(response).toEqual(termQueryLocalizedFindMock);
79+
});
5880
});

‎test/unit/term.spec.ts‎

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { AxiosInstance, httpClient } from '@contentstack/core';
22
import MockAdapter from 'axios-mock-adapter';
3-
import { termQueryFindResponseDataMock, termLocalesResponseDataMock, termAncestorsResponseDataMock, termDescendantsResponseDataMock } from '../utils/mocks';
3+
import { termQueryFindResponseDataMock, termLocalesResponseDataMock, termAncestorsResponseDataMock, termDescendantsResponseDataMock, termLocalizedFetchMock } from '../utils/mocks';
44
import { MOCK_CLIENT_OPTIONS } from '../utils/constant';
55
import { Term } from '../../src/taxonomy/term';
66
import { Taxonomy } from '../../src/taxonomy';
@@ -75,4 +75,11 @@ describe('Term class', () => {
7575

7676
await term.param('depth', 1).addParams({ locale: 'fr-fr' }).ancestors();
7777
});
78+
79+
it('should fetch localized term when fetch is called with locale', async () => {
80+
mockClient.onGet('/taxonomies/taxonomy_testing/terms/term1').reply(200, termLocalizedFetchMock);
81+
82+
const response = await term.fetch('hi-in');
83+
expect(response).toEqual(termLocalizedFetchMock.term);
84+
});
7885
});

‎test/utils/mocks.ts‎

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1855,6 +1855,71 @@ const termQueryFindResponseDataMock = {
18551855
]
18561856
}
18571857

1858+
const taxonomyLocalizedFetchMock = {
1859+
"taxonomy": {
1860+
"uid": "taxonomy_testing",
1861+
"locale": "hi-in",
1862+
"name": "टैक्सोनॉमी परीक्षण",
1863+
"description": "",
1864+
"created_at": "2025-10-10T06:42:48.644Z",
1865+
"updated_at": "2025-10-10T06:42:48.644Z",
1866+
"created_by": "created_by",
1867+
"updated_by": "updated_by",
1868+
"publish_details": {
1869+
"time": "2025-10-10T08:01:48.174Z",
1870+
"user": "user",
1871+
"environment": "env",
1872+
"locale": "hi-in"
1873+
}
1874+
}
1875+
};
1876+
1877+
const termLocalizedFetchMock = {
1878+
"term": {
1879+
"taxonomy_uid": "taxonomy_testing",
1880+
"uid": "term1",
1881+
"locale": "hi-in",
1882+
"name": "टर्म एक",
1883+
"ancestors": [{ "uid": "taxonomy_testing", "name": "taxonomy testing", "type": "TAXONOMY" }],
1884+
"depth": 1,
1885+
"parent_uid": null,
1886+
"created_by": "created_by",
1887+
"created_at": "2025-10-10T06:43:13.799Z",
1888+
"updated_by": "updated_by",
1889+
"updated_at": "2025-10-10T06:43:13.799Z",
1890+
"publish_details": {
1891+
"time": "2025-10-10T08:01:48.351Z",
1892+
"user": "user",
1893+
"environment": "environment",
1894+
"locale": "hi-in"
1895+
}
1896+
}
1897+
};
1898+
1899+
const termQueryLocalizedFindMock = {
1900+
"terms": [
1901+
{
1902+
"taxonomy_uid": "taxonomy_testing",
1903+
"uid": "term1",
1904+
"locale": "hi-in",
1905+
"name": "टर्म एक",
1906+
"ancestors": [{ "uid": "taxonomy_testing", "name": "taxonomy testing", "type": "TAXONOMY" }],
1907+
"depth": 1,
1908+
"parent_uid": null,
1909+
"created_by": "created_by",
1910+
"created_at": "2025-10-10T06:43:13.799Z",
1911+
"updated_by": "updated_by",
1912+
"updated_at": "2025-10-10T06:43:13.799Z",
1913+
"publish_details": {
1914+
"time": "2025-10-10T08:01:48.351Z",
1915+
"user": "user",
1916+
"environment": "environment",
1917+
"locale": "hi-in"
1918+
}
1919+
}
1920+
]
1921+
};
1922+
18581923
const syncResult: any = { ...axiosGetMock.data };
18591924

18601925
export {
@@ -1873,4 +1938,7 @@ export {
18731938
termLocalesResponseDataMock,
18741939
termAncestorsResponseDataMock,
18751940
termDescendantsResponseDataMock,
1941+
taxonomyLocalizedFetchMock,
1942+
termLocalizedFetchMock,
1943+
termQueryLocalizedFindMock,
18761944
};

0 commit comments

Comments
 (0)