Skip to content

Commit c213dd8

Browse files
feat: Add Term and TermQuery classes for enhanced taxonomy term management
1 parent 056fc6d commit c213dd8

11 files changed

Lines changed: 215 additions & 4 deletions

File tree

src/lib/taxonomy.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
import { AxiosInstance, getData } from '@contentstack/core';
2+
import { TermQuery } from './term-query';
3+
import { Term } from './term';
24

35
export class Taxonomy {
46
private _client: AxiosInstance;
@@ -13,6 +15,14 @@ export class Taxonomy {
1315
this._urlPath = `/taxonomy-manager/${this._taxonomyUid}`; // TODO: change to /taxonomies/${this._taxonomyUid}
1416
}
1517

18+
term(uid: string): Term;
19+
term(): TermQuery;
20+
term(uid?: string): Term | TermQuery {
21+
if (uid) return new Term(this._client, this._taxonomyUid, uid);
22+
23+
return new TermQuery(this._client, this._taxonomyUid);
24+
}
25+
1626
async fetch<T>(): Promise<T> {
1727
const response = await getData(this._client, this._urlPath);
1828

src/lib/term-query.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import { AxiosInstance, getData } from '@contentstack/core';
2+
import { FindResponse } from './types';
3+
4+
export class TermQuery {
5+
private _taxonomyUid: string;
6+
private _client: AxiosInstance;
7+
private _urlPath: string;
8+
_queryParams: { [key: string]: string | number } = {};
9+
10+
constructor(client: AxiosInstance, taxonomyUid: string) {
11+
this._client = client;
12+
this._taxonomyUid = taxonomyUid;
13+
this._urlPath = `/taxonomy-manager/${this._taxonomyUid}/terms`;
14+
}
15+
16+
async find<T>(): Promise<FindResponse<T>> {
17+
const response = await getData(this._client, this._urlPath, { params: this._queryParams });
18+
return response as FindResponse<T>;
19+
}
20+
}

src/lib/term.ts

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import { AxiosInstance, getData } from "@contentstack/core";
2+
3+
export class Term {
4+
protected _client: AxiosInstance;
5+
private _taxonomyUid: string;
6+
private _termUid: string;
7+
private _urlPath: string;
8+
9+
constructor(client: AxiosInstance, taxonomyUid: string, termUid: string) {
10+
this._client = client;
11+
this._taxonomyUid = taxonomyUid;
12+
this._termUid = termUid;
13+
this._urlPath = `/taxonomy-manager/${this._taxonomyUid}/terms/${this._termUid}`; // TODO: change to /taxonomies
14+
}
15+
async fetch<T>(): Promise<T> {
16+
const response = await getData(this._client, this._urlPath);
17+
18+
if (response.term) return response.term as T;
19+
20+
return response;
21+
}
22+
}

src/lib/types.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -317,6 +317,8 @@ export interface FindResponse<T> {
317317
assets?: T[];
318318
global_fields?: T[];
319319
count?: number;
320+
taxonomies?: T[];
321+
terms?: T[];
320322
}
321323

322324
export interface LivePreviewQuery {

test/api/term-query.spec.ts

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import { TermQuery } from "../../src/lib/term-query";
2+
import { stackInstance } from "../utils/stack-instance";
3+
import { TTerm } from "./types";
4+
5+
const stack = stackInstance();
6+
7+
describe("Terms API test cases", () => {
8+
it("should check for terms is defined", async () => {
9+
const result = await makeTerms("taxonomy_testing").find<TTerm>();
10+
if (result.terms) {
11+
expect(result.terms).toBeDefined();
12+
expect(result.terms[0].taxonomy_uid).toBeDefined();
13+
expect(result.terms[0].uid).toBeDefined();
14+
expect(result.terms[0].created_by).toBeDefined();
15+
expect(result.terms[0].updated_by).toBeDefined();
16+
}
17+
});
18+
});
19+
function makeTerms(taxonomyUid = ""): TermQuery {
20+
const terms = stack.taxonomy(taxonomyUid).term();
21+
22+
return terms;
23+
}

test/api/term.spec.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import { Term } from "../../src/lib/term";
2+
import { stackInstance } from "../utils/stack-instance";
3+
import { TTerm } from "./types";
4+
5+
const stack = stackInstance();
6+
7+
describe("Terms API test cases", () => {
8+
it("should get a term by uid", async () => {
9+
const result = await makeTerms("term1").fetch<TTerm>();
10+
expect(result).toBeDefined();
11+
expect(result.taxonomy_uid).toBeDefined();
12+
expect(result.uid).toBeDefined();
13+
expect(result.created_by).toBeDefined();
14+
expect(result.updated_by).toBeDefined();
15+
});
16+
});
17+
function makeTerms(termUid = ""): Term {
18+
const terms = stack.taxonomy("taxonomy_testing").term(termUid);
19+
return terms;
20+
}

test/api/types.ts

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -95,11 +95,29 @@ export interface TTaxonomy {
9595
uid: string;
9696
name: string;
9797
description?: string;
98-
terms_count: number;
98+
terms_count?: number;
9999
created_at: string;
100100
updated_at: string;
101101
created_by: string;
102102
updated_by: string;
103103
type: string;
104-
publish_details: PublishDetails;
104+
publish_details?: PublishDetails;
105+
}
106+
107+
export interface TTerms {
108+
terms: TTerm[];
109+
}
110+
111+
export interface TTerm {
112+
taxonomy_uid: string;
113+
uid: string;
114+
ancestors: TTerm[];
115+
name: string;
116+
created_by: string;
117+
created_at: string;
118+
updated_by: string;
119+
updated_at: string;
120+
children_count?: number;
121+
depth?: number;
122+
publish_details?: PublishDetails;
105123
}

test/unit/taxonomy.spec.ts

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ import { AxiosInstance, httpClient } from '@contentstack/core';
44
import MockAdapter from 'axios-mock-adapter';
55
import { taxonomyFindResponseDataMock } from '../utils/mocks';
66
import { MOCK_CLIENT_OPTIONS } from '../utils/constant';
7+
import { Term } from '../../src/lib/term';
8+
import { TermQuery } from '../../src/lib/term-query';
79

810
describe('ta class', () => {
911
let taxonomies: TaxonomyQuery;
@@ -21,6 +23,16 @@ describe('ta class', () => {
2123
taxonomy = new Taxonomy(client, 'taxonomy_testing');
2224
});
2325

26+
it('should give term instance when term method is called with termUid', () => {
27+
const query = taxonomy.term('termUid');
28+
expect(query).toBeInstanceOf(Term);
29+
});
30+
31+
it('should give term query instance when term method is called without termUid', () => {
32+
const query = taxonomy.term()
33+
expect(query).toBeInstanceOf(TermQuery);
34+
});
35+
2436
it('should return all taxonomies in the response data when successful', async () => {
2537
mockClient.onGet('/taxonomy-manager').reply(200, taxonomyFindResponseDataMock); //TODO: change to /taxonomies
2638
const response = await taxonomies.find();
@@ -30,6 +42,6 @@ describe('ta class', () => {
3042
it('should return single taxonomy in the response data when successful', async () => {
3143
mockClient.onGet('/taxonomy-manager/taxonomy_testing').reply(200, taxonomyFindResponseDataMock.taxonomies[0]); //TODO: change to /taxonomies/taxonomyUid
3244
const response = await taxonomy.fetch();
33-
expect(response).toEqual(taxonomyFindResponseDataMock.taxonomies[0]); //TODO: change to taxonomyFindResponseDataMock
45+
expect(response).toEqual(taxonomyFindResponseDataMock.taxonomies[0]);
3446
});
3547
});

test/unit/term-query.spec.ts

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import { TermQuery } from '../../src/lib/term-query';
2+
import { AxiosInstance, httpClient } from '@contentstack/core';
3+
import MockAdapter from 'axios-mock-adapter';
4+
import { TermQueryFindResponseDataMock } from '../utils/mocks';
5+
import { MOCK_CLIENT_OPTIONS } from '../utils/constant';
6+
7+
describe('TermQuery class', () => {
8+
let termQuery: TermQuery;
9+
let client: AxiosInstance;
10+
let mockClient: MockAdapter;
11+
12+
beforeAll(() => {
13+
client = httpClient(MOCK_CLIENT_OPTIONS);
14+
mockClient = new MockAdapter(client as any);
15+
});
16+
17+
beforeEach(() => {
18+
termQuery = new TermQuery(client, 'taxonomy_testing');
19+
});
20+
21+
it('should return response data when successful', async () => {
22+
mockClient.onGet('/taxonomy-manager/taxonomy_testing/terms').reply(200, TermQueryFindResponseDataMock);
23+
const response = await termQuery.find();
24+
expect(response).toEqual(TermQueryFindResponseDataMock);
25+
});
26+
});

test/unit/term.spec.ts

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import { AxiosInstance, httpClient } from '@contentstack/core';
2+
import MockAdapter from 'axios-mock-adapter';
3+
import { TermQueryFindResponseDataMock } from '../utils/mocks';
4+
import { MOCK_CLIENT_OPTIONS } from '../utils/constant';
5+
import { Term } from '../../src/lib/term';
6+
import { Taxonomy } from '../../src/lib/taxonomy';
7+
8+
describe('Term class', () => {
9+
let term: Term;
10+
let client: AxiosInstance;
11+
let mockClient: MockAdapter;
12+
13+
beforeAll(() => {
14+
client = httpClient(MOCK_CLIENT_OPTIONS);
15+
mockClient = new MockAdapter(client as any);
16+
});
17+
18+
beforeEach(() => {
19+
term = new Term(client, 'taxonomy_testing', 'term1');
20+
});
21+
22+
it('should fetch the term by uid response when fetch method is called', async () => {
23+
mockClient.onGet('/taxonomy-manager/taxonomy_testing/terms/term1').reply(200, TermQueryFindResponseDataMock.terms[0]); //TODO: change to /taxonomies
24+
25+
const response = await term.fetch();
26+
expect(response).toEqual(TermQueryFindResponseDataMock.terms[0]);
27+
});
28+
});

0 commit comments

Comments
 (0)