diff --git a/src/lib/taxonomy.ts b/src/lib/taxonomy.ts index 6e7a8745..84b05072 100644 --- a/src/lib/taxonomy.ts +++ b/src/lib/taxonomy.ts @@ -1,4 +1,6 @@ import { AxiosInstance, getData } from '@contentstack/core'; +import { TermQuery } from './term-query'; +import { Term } from './term'; export class Taxonomy { private _client: AxiosInstance; @@ -13,6 +15,14 @@ export class Taxonomy { this._urlPath = `/taxonomy-manager/${this._taxonomyUid}`; // TODO: change to /taxonomies/${this._taxonomyUid} } + term(uid: string): Term; + term(): TermQuery; + term(uid?: string): Term | TermQuery { + if (uid) return new Term(this._client, this._taxonomyUid, uid); + + return new TermQuery(this._client, this._taxonomyUid); + } + async fetch(): Promise { const response = await getData(this._client, this._urlPath); diff --git a/src/lib/term-query.ts b/src/lib/term-query.ts new file mode 100644 index 00000000..23a8698f --- /dev/null +++ b/src/lib/term-query.ts @@ -0,0 +1,20 @@ +import { AxiosInstance, getData } from '@contentstack/core'; +import { FindResponse } from './types'; + +export class TermQuery { + private _taxonomyUid: string; + private _client: AxiosInstance; + private _urlPath: string; + _queryParams: { [key: string]: string | number } = {}; + + constructor(client: AxiosInstance, taxonomyUid: string) { + this._client = client; + this._taxonomyUid = taxonomyUid; + this._urlPath = `/taxonomy-manager/${this._taxonomyUid}/terms`; + } + + async find(): Promise> { + const response = await getData(this._client, this._urlPath, { params: this._queryParams }); + return response as FindResponse; + } +} diff --git a/src/lib/term.ts b/src/lib/term.ts new file mode 100644 index 00000000..615e95f5 --- /dev/null +++ b/src/lib/term.ts @@ -0,0 +1,22 @@ +import { AxiosInstance, getData } from "@contentstack/core"; + +export class Term { + protected _client: AxiosInstance; + private _taxonomyUid: string; + private _termUid: string; + private _urlPath: string; + + constructor(client: AxiosInstance, taxonomyUid: string, termUid: string) { + this._client = client; + this._taxonomyUid = taxonomyUid; + this._termUid = termUid; + this._urlPath = `/taxonomy-manager/${this._taxonomyUid}/terms/${this._termUid}`; // TODO: change to /taxonomies + } + async fetch(): Promise { + const response = await getData(this._client, this._urlPath); + + if (response.term) return response.term as T; + + return response; + } +} diff --git a/src/lib/types.ts b/src/lib/types.ts index e19a0326..a5106675 100644 --- a/src/lib/types.ts +++ b/src/lib/types.ts @@ -317,6 +317,8 @@ export interface FindResponse { assets?: T[]; global_fields?: T[]; count?: number; + taxonomies?: T[]; + terms?: T[]; } export interface LivePreviewQuery { diff --git a/test/api/term-query.spec.ts b/test/api/term-query.spec.ts new file mode 100644 index 00000000..58f59574 --- /dev/null +++ b/test/api/term-query.spec.ts @@ -0,0 +1,23 @@ +import { TermQuery } from "../../src/lib/term-query"; +import { stackInstance } from "../utils/stack-instance"; +import { TTerm } from "./types"; + +const stack = stackInstance(); + +describe("Terms API test cases", () => { + it("should check for terms is defined", async () => { + const result = await makeTerms("taxonomy_testing").find(); + if (result.terms) { + expect(result.terms).toBeDefined(); + expect(result.terms[0].taxonomy_uid).toBeDefined(); + expect(result.terms[0].uid).toBeDefined(); + expect(result.terms[0].created_by).toBeDefined(); + expect(result.terms[0].updated_by).toBeDefined(); + } + }); +}); +function makeTerms(taxonomyUid = ""): TermQuery { + const terms = stack.taxonomy(taxonomyUid).term(); + + return terms; +} diff --git a/test/api/term.spec.ts b/test/api/term.spec.ts new file mode 100644 index 00000000..72c1c6eb --- /dev/null +++ b/test/api/term.spec.ts @@ -0,0 +1,20 @@ +import { Term } from "../../src/lib/term"; +import { stackInstance } from "../utils/stack-instance"; +import { TTerm } from "./types"; + +const stack = stackInstance(); + +describe("Terms API test cases", () => { + it("should get a term by uid", async () => { + const result = await makeTerms("term1").fetch(); + expect(result).toBeDefined(); + expect(result.taxonomy_uid).toBeDefined(); + expect(result.uid).toBeDefined(); + expect(result.created_by).toBeDefined(); + expect(result.updated_by).toBeDefined(); + }); +}); +function makeTerms(termUid = ""): Term { + const terms = stack.taxonomy("taxonomy_testing").term(termUid); + return terms; +} diff --git a/test/api/types.ts b/test/api/types.ts index 11197b6f..f59f73cd 100644 --- a/test/api/types.ts +++ b/test/api/types.ts @@ -95,11 +95,29 @@ export interface TTaxonomy { uid: string; name: string; description?: string; - terms_count: number; + terms_count?: number; created_at: string; updated_at: string; created_by: string; updated_by: string; type: string; - publish_details: PublishDetails; + publish_details?: PublishDetails; +} + +export interface TTerms { + terms: TTerm[]; +} + +export interface TTerm { + taxonomy_uid: string; + uid: string; + ancestors: TTerm[]; + name: string; + created_by: string; + created_at: string; + updated_by: string; + updated_at: string; + children_count?: number; + depth?: number; + publish_details?: PublishDetails; } \ No newline at end of file diff --git a/test/unit/taxonomy.spec.ts b/test/unit/taxonomy.spec.ts index 0c4670e5..5db38cb6 100644 --- a/test/unit/taxonomy.spec.ts +++ b/test/unit/taxonomy.spec.ts @@ -4,6 +4,8 @@ import { AxiosInstance, httpClient } from '@contentstack/core'; import MockAdapter from 'axios-mock-adapter'; import { taxonomyFindResponseDataMock } from '../utils/mocks'; import { MOCK_CLIENT_OPTIONS } from '../utils/constant'; +import { Term } from '../../src/lib/term'; +import { TermQuery } from '../../src/lib/term-query'; describe('ta class', () => { let taxonomies: TaxonomyQuery; @@ -21,6 +23,16 @@ describe('ta class', () => { taxonomy = new Taxonomy(client, 'taxonomy_testing'); }); + it('should give term instance when term method is called with termUid', () => { + const query = taxonomy.term('termUid'); + expect(query).toBeInstanceOf(Term); + }); + + it('should give term query instance when term method is called without termUid', () => { + const query = taxonomy.term() + expect(query).toBeInstanceOf(TermQuery); + }); + it('should return all taxonomies in the response data when successful', async () => { mockClient.onGet('/taxonomy-manager').reply(200, taxonomyFindResponseDataMock); //TODO: change to /taxonomies const response = await taxonomies.find(); @@ -30,6 +42,6 @@ describe('ta class', () => { it('should return single taxonomy in the response data when successful', async () => { mockClient.onGet('/taxonomy-manager/taxonomy_testing').reply(200, taxonomyFindResponseDataMock.taxonomies[0]); //TODO: change to /taxonomies/taxonomyUid const response = await taxonomy.fetch(); - expect(response).toEqual(taxonomyFindResponseDataMock.taxonomies[0]); //TODO: change to taxonomyFindResponseDataMock + expect(response).toEqual(taxonomyFindResponseDataMock.taxonomies[0]); }); }); diff --git a/test/unit/term-query.spec.ts b/test/unit/term-query.spec.ts new file mode 100644 index 00000000..a96019d0 --- /dev/null +++ b/test/unit/term-query.spec.ts @@ -0,0 +1,26 @@ +import { TermQuery } from '../../src/lib/term-query'; +import { AxiosInstance, httpClient } from '@contentstack/core'; +import MockAdapter from 'axios-mock-adapter'; +import { termQueryFindResponseDataMock } from '../utils/mocks'; +import { MOCK_CLIENT_OPTIONS } from '../utils/constant'; + +describe('TermQuery class', () => { + let termQuery: TermQuery; + let client: AxiosInstance; + let mockClient: MockAdapter; + + beforeAll(() => { + client = httpClient(MOCK_CLIENT_OPTIONS); + mockClient = new MockAdapter(client as any); + }); + + beforeEach(() => { + termQuery = new TermQuery(client, 'taxonomy_testing'); + }); + + it('should return response data when successful', async () => { + mockClient.onGet('/taxonomy-manager/taxonomy_testing/terms').reply(200, termQueryFindResponseDataMock); + const response = await termQuery.find(); + expect(response).toEqual(termQueryFindResponseDataMock); + }); +}); diff --git a/test/unit/term.spec.ts b/test/unit/term.spec.ts new file mode 100644 index 00000000..65d4140e --- /dev/null +++ b/test/unit/term.spec.ts @@ -0,0 +1,28 @@ +import { AxiosInstance, httpClient } from '@contentstack/core'; +import MockAdapter from 'axios-mock-adapter'; +import { termQueryFindResponseDataMock } from '../utils/mocks'; +import { MOCK_CLIENT_OPTIONS } from '../utils/constant'; +import { Term } from '../../src/lib/term'; +import { Taxonomy } from '../../src/lib/taxonomy'; + +describe('Term class', () => { + let term: Term; + let client: AxiosInstance; + let mockClient: MockAdapter; + + beforeAll(() => { + client = httpClient(MOCK_CLIENT_OPTIONS); + mockClient = new MockAdapter(client as any); + }); + + beforeEach(() => { + term = new Term(client, 'taxonomy_testing', 'term1'); + }); + + it('should fetch the term by uid response when fetch method is called', async () => { + mockClient.onGet('/taxonomy-manager/taxonomy_testing/terms/term1').reply(200, termQueryFindResponseDataMock.terms[0]); //TODO: change to /taxonomies + + const response = await term.fetch(); + expect(response).toEqual(termQueryFindResponseDataMock.terms[0]); + }); +}); diff --git a/test/utils/mocks.ts b/test/utils/mocks.ts index 27e79be3..82c4becc 100644 --- a/test/utils/mocks.ts +++ b/test/utils/mocks.ts @@ -1698,6 +1698,35 @@ const taxonomyFindResponseDataMock = { } ] } +const termQueryFindResponseDataMock = { + "terms": [ + { + "taxonomy_uid": "taxonomy_testing", + "uid": "term1", + "ancestors": [ + { + "uid": "taxonomy_testing", + "name": "taxonomy testing", + "type": "TAXONOMY" + } + ], + "name": "term1", + "created_by": "created_by", + "created_at": "2025-10-10T06:43:13.799Z", + "updated_by": "updated_by", + "updated_at": "2025-10-10T06:43:13.799Z", + "children_count": 0, + "depth": 1, + "ACL": {}, + "publish_details": { + "time": "2025-10-10T08:01:48.351Z", + "user": "user", + "environment": "environment", + "locale": "en-us" + } + } +] +} const syncResult: any = { ...axiosGetMock.data }; @@ -1712,5 +1741,6 @@ export { entryFetchMock, gfieldFetchDataMock, gfieldQueryFindResponseDataMock, - taxonomyFindResponseDataMock + taxonomyFindResponseDataMock, + termQueryFindResponseDataMock, };