diff --git a/src/quran/resource.test.ts b/src/quran/resource.test.ts new file mode 100644 index 0000000..11cedf0 --- /dev/null +++ b/src/quran/resource.test.ts @@ -0,0 +1,131 @@ +import resources from "./resource"; + +describe("Fetching the recitation by id", () => { + beforeEach(() => jest.clearAllMocks()); + + it("Should fetch the recitation info of a specific recitaion", async () => { + const res: any = await resources.getRecitationInfo('1'); + expect(res).toHaveProperty('info'); + expect(res.info).toHaveProperty('id'); + expect(res.info).toHaveProperty('info'); + }); + + it("Should return a response with 404 status code", async () => { + const res: any = await resources.getRecitationInfo('101839'); + expect(res).toHaveProperty('status'); + expect(res.status).toEqual(404); + }); +}); + +describe("Fetching the translation info by translation_id", () => { + beforeEach(() => jest.clearAllMocks()); + + it("Should fetch the translation info of a specific recitaion by translation_id", async () => { + const res: any = await resources.getTranslationInfo('23'); + expect(res).toHaveProperty('info'); + expect(res.info).toHaveProperty('id'); + expect(res.info).toHaveProperty('info'); + expect(res.info.info).toBeNull(); + }); + + it("Should return a response with 404 status code", async () => { + const res: any = await resources.getTranslationInfo('101839'); + expect(res).toHaveProperty('status'); + expect(res.status).toEqual(404); + }); +}); + +describe("Fetching all translations info by language", () => { + beforeEach(() => jest.clearAllMocks()); + + it("Should fetch all translations info by language", async () => { + const res: any = await resources.getTranslations('ha'); + expect(res).toHaveProperty('translations'); + }); + + it("Should reject with a error if an invalid language iso code is provided", async () => { + try { + const res: any = await resources.getTranslations('abcd'); + } catch (err: any) { + expect(err.message).toEqual('Provided language is not supported'); + } + }); +}); + +describe("Fetching all tafsirs info by language", () => { + beforeEach(() => jest.clearAllMocks()); + + it("Should fetch all tafsirs info by language", async () => { + const res: any = await resources.getTafsirs('ha'); + expect(res).toHaveProperty('tafsirs'); + }); + + it("Should reject with a error if an invalid language iso code is provided", async () => { + try { + const res: any = await resources.getTafsirs('abcd'); + } catch (err: any) { + expect(err.message).toEqual('Provided language is not supported'); + } + }); +}); + +describe("Fetching tafsir info by tafsir_id", () => { + beforeEach(() => jest.clearAllMocks()); + + it("Should fetch tafsir info by tafsir_id", async () => { + const res: any = await resources.getTafsirInfo('381'); + expect(res).toHaveProperty('info'); + expect(res.info).toHaveProperty('id'); + expect(res.info.id).toBe(381); + expect(res.info.info).toBe(""); + }); + + it("Should reject with a error if an invalid tafsir_id is provided", async () => { + const res: any = await resources.getTafsirInfo('1'); + expect(res).toHaveProperty('status'); + expect(res.status).toEqual(404); + expect(res.error).toBe('Tafsir not found'); + }); +}); + +describe("Fetching all recitation styles", () => { + beforeEach(() => jest.clearAllMocks()); + + it("Should fetch all recitation styles", async () => { + const res: any = await resources.getRecitationStyles(); + expect(res).toHaveProperty('recitation_styles'); + expect(res.recitation_styles).toHaveProperty('mujawwad'); + expect(res.recitation_styles).toHaveProperty('murattal'); + expect(res.recitation_styles).toHaveProperty('muallim'); + }); +}); + +describe("Fetching all languages", () => { + beforeEach(() => jest.clearAllMocks()); + + it("Should fetch all languages", async () => { + const res: any = await resources.getLanguages(); + expect(res).toHaveProperty('languages');; + expect(res.languages).toBeInstanceOf(Array); + }); +}); + +describe("Fetching all Chapter infos", () => { + beforeEach(() => jest.clearAllMocks()); + + it("Should fetch all Chapter infos", async () => { + const res: any = await resources.getChapterInfos(); + expect(res).toHaveProperty('chapter_infos');; + expect(res.chapter_infos).toBeInstanceOf(Array); + }); +}); + +describe("Fetching all Media verses", () => { + beforeEach(() => jest.clearAllMocks()); + + it("Should fetch all Media verses", async () => { + const res: any = await resources.getVerseMedias(); + expect(res).toHaveProperty('verse_media');; + expect(res.verse_media).toBeInstanceOf(Array); + }); +}); \ No newline at end of file diff --git a/src/quran/resource.ts b/src/quran/resource.ts new file mode 100644 index 0000000..4e7fe48 --- /dev/null +++ b/src/quran/resource.ts @@ -0,0 +1,83 @@ +import { AxiosError } from "axios"; +import Api from "../api"; +import { ResourceApi, RecitaionInfo, TranslationInfo, TranslationResponse, TafsirsResponse, TafsirInfoResponse, RecitationStyleResponse, LanguageResponse, ChapterInfos, VerseMediaResponse } from "../types"; +import { handleError, handleResponse } from "../utils"; + +const api = Api(); + +const ALLOWED_LANGUAGES = new Set(['en', 'ur', 'bn', 'tr', 'es', 'fr', 'bs', 'ru', 'ml', 'id', 'uz', 'nl', 'de', 'tg', 'ta', 'ja', 'it', 'vi', 'zh', 'sq', 'fa', 'bg', 'bm', 'ha', 'pt', 'ro', 'hi', 'sw', 'kk', 'th', 'tl', 'km', 'as', 'ko', 'so', 'az', 'ku', 'dv', 'ms', 'prs', 'zgh', 'am', 'ce', 'cs', 'fi', 'gu', 'he', 'ka', 'kn', 'ks', 'lg', 'mk', 'mr', 'mrn', 'ne', 'no', 'om', 'pl', 'ps', 'rw', 'sd', 'se', 'si', 'sr', 'sv', 'te', 'tt', 'ug', 'uk', 'sq', 'yo']); + +const resources: ResourceApi = { + getRecitationInfo(recitation_id: string): Promise { + if (!recitation_id) return Promise.reject(new Error('Recitation ID is required')); + return new Promise((resolve, reject) => { + api.get(`/resources/recitations/${recitation_id}/info`) + .then(handleResponse(resolve)) + .catch(handleError(reject)); + }); + }, + getTranslationInfo(translation_id: string): Promise { + if (!translation_id) return Promise.reject(new Error('Translation ID is required')); + return new Promise((resolve, reject) => { + api.get(`/resources/translations/${translation_id}/info`) + .then(handleResponse(resolve)) + .catch(handleError(reject)); + }); + }, + getTranslations(language: string = 'en'): Promise { + const isLanguageSupported = ALLOWED_LANGUAGES.has(language); + if (!isLanguageSupported) return Promise.reject(new Error("Provided language is not supported")); + return new Promise((resolve, reject) => { + api.get(`/resources/translations?${new URLSearchParams({ language })}`) + .then(handleResponse(resolve)) + .catch(handleError(reject)); + }); + }, + getTafsirs(language: string = 'en'): Promise { + const isLanguageSupported = ALLOWED_LANGUAGES.has(language); + if (!isLanguageSupported) return Promise.reject(new Error("Provided language is not supported")); + return new Promise((resolve, reject) => { + api.get(`/resources/tafsirs?${new URLSearchParams({ language })}`) + .then(handleResponse(resolve)) + .catch(handleError(reject)); + }); + }, + getTafsirInfo(tafsir_id: string): Promise { + if (!tafsir_id) return Promise.reject(new Error('Tafsir ID is required')); + return new Promise((resolve, reject) => { + api.get(`/resources/tafsirs/${tafsir_id}/info`) + .then(handleResponse(resolve)) + .catch(handleError(reject)); + }); + }, + getRecitationStyles(): Promise { + return new Promise((resolve, reject) => { + api.get('/resources/recitation_styles') + .then(handleResponse(resolve)) + .catch(handleError(reject)); + }); + }, + getLanguages(): Promise { + return new Promise((resolve, reject) => { + api.get('/resources/languages') + .then(handleResponse(resolve)) + .catch(handleError(reject)); + }); + }, + getChapterInfos(): Promise { + return new Promise((resolve, reject) => { + api.get(`/resources/chapter_infos`) + .then(handleResponse(resolve)) + .catch(handleError(reject)); + }); + }, + getVerseMedias(): Promise { + return new Promise((resolve, reject) => { + api.get(`/resources/verse_media`) + .then(handleResponse(resolve)) + .catch(handleError(reject)); + }); + } +}; + +export default resources; \ No newline at end of file diff --git a/src/types.ts b/src/types.ts index 7283584..5926fd3 100644 --- a/src/types.ts +++ b/src/types.ts @@ -177,4 +177,102 @@ export interface JuzResponse { export interface JuzApi { getAllJuzs: () => Promise; +}; + +export interface RecitaionInfo { + info: Info; +} + +export interface Info { + id: number; + info: any; +}; + + +export interface TranslationInfo { + info: Info; +}; + +export interface Root { + translations: Translation[]; +}; + +export interface Translation { + id: number; + name: string; + author_name: string; + slug: string; + language_name: string; + translated_name: TranslatedName; +}; + +export interface TranslationResponse { + translations: Translation[]; +}; + +export interface TafsirsResponse { + tafsirs: Translation[]; +}; + +export interface TafsirInfoResponse { + id: number; + info: string | null; +}; + +export interface RecitationStyle { + mujawwad: string; + murattal: string; + muallim: string; +}; + +export interface RecitationStyleResponse { + recitation_styles: RecitationStyle[]; +}; + +export interface Languages { + id: number; + name: string; + iso_code: string; + native_name: string; + direction: string; + translations_count: number; + translated_name: TranslatedName; +}; + +export interface LanguageResponse { + languagess: Languages[]; +}; + +export interface TranslatedName { + name: string; + language_name: string; +}; + +export interface ChapterInfos { + chapter_infos: Translation[]; +}; + +export interface VerseMedia { + id: number; + name: string; + author_name: string; + slug: string; + language_name: string; + translated_name: TranslatedName; +}; + +export interface VerseMediaResponse { + verse_media: VerseMedia[]; +}; + +export interface ResourceApi { + getRecitationInfo: (recitation_id: string) => Promise; + getTranslationInfo: (translation_id: string) => Promise; + getTranslations: (language?: string) => Promise; + getTafsirs: (language?: string) => Promise; + getTafsirInfo: (tafsir_id: string) => Promise; + getRecitationStyles: () => Promise; + getLanguages: () => Promise; + getChapterInfos: () => Promise; + getVerseMedias: () => Promise; }; \ No newline at end of file