From 585d4f0f339577957e2b63e6ffd7582b5dba4a80 Mon Sep 17 00:00:00 2001 From: Kevin Kee Date: Sat, 8 Jan 2022 14:30:30 +0900 Subject: [PATCH 1/2] Add method to get featured content by date resolves #34 --- source/errors.ts | 7 +++ source/index.ts | 30 +++++++-- source/optionTypes.ts | 6 ++ source/resultTypes.ts | 68 ++++++++++++++++++++ source/utils.ts | 7 +++ test/featuredContent.test.ts | 39 ++++++++++++ test/samples.ts | 119 +++++++++++++++++++++++++++++++++++ 7 files changed, 272 insertions(+), 4 deletions(-) create mode 100644 test/featuredContent.test.ts diff --git a/source/errors.ts b/source/errors.ts index a14bfa1..0821bf5 100644 --- a/source/errors.ts +++ b/source/errors.ts @@ -119,6 +119,13 @@ export class eventsError extends wikiError { } } +export class fcError extends wikiError { + constructor(message: string) { + super(message); + this.name = 'featuredContentError'; + } +} + export class pdfError extends wikiError { constructor(message: string) { super(message); diff --git a/source/index.ts b/source/index.ts index 1e63932..f637017 100644 --- a/source/index.ts +++ b/source/index.ts @@ -1,21 +1,21 @@ import request, { makeRestRequest, setAPIUrl } from './request' -import { pageOptions, searchOptions, geoOptions, listOptions, eventOptions, randomFormats, pdfOptions, citationFormat } from './optionTypes'; +import { pageOptions, searchOptions, geoOptions, listOptions, eventOptions, fcOptions, randomFormats, pdfOptions, citationFormat } from './optionTypes'; import Page, { intro, images, html, content, categories, links, coordinates, langLinks, references, infobox, tables, summary, related, media, mobileHtml, pdf, citation } from './page'; -import { coordinatesResult, eventResult, geoSearchResult, imageResult, langLinksResult, languageResult, +import { coordinatesResult, eventResult, featuredContentResult, geoSearchResult, imageResult, langLinksResult, languageResult, mobileSections, relatedResult, title, wikiMediaResult, wikiSearchResult, wikiSummary, notFound } from './resultTypes'; import { categoriesError, - contentError, coordinatesError, eventsError, geoSearchError, htmlError, imageError, infoboxError, + contentError, coordinatesError, eventsError, fcError, geoSearchError, htmlError, imageError, infoboxError, introError, linksError, mediaError, pageError, relatedError, searchError, summaryError, wikiError, pdfError, citationError } from './errors'; import { MSGS } from './messages'; -import { getCurrentDay, getCurrentMonth, setPageId, setPageIdOrTitleParam, setTitleForPage } from './utils'; +import { getCurrentDay, getCurrentMonth, getCurrentYear, setPageId, setPageIdOrTitleParam, setTitleForPage } from './utils'; /** * The default wiki export @@ -529,6 +529,28 @@ wiki.onThisDay = async (eventOptions: eventOptions = {}): Promise = } } +/** + * Returns featured content for a given day + * + * @remarks + * The api returns content featured at a particular date + * + * @param fcOptions - the year/month/day of featured content by {@link fcOptions | eventOptions} + * @returns Returns the results as array of {@link fcResult | fcResult} + */ +wiki.featuredContent = async (fcOptions: fcOptions = {}): Promise => { + try { + const yyyy = (fcOptions.year || getCurrentYear()).toString() + const mm = (fcOptions.month || getCurrentMonth()).toString().padStart(2, "0") + const dd = (fcOptions.day || getCurrentDay()).toString().padStart(2, "0") + const path = `feed/featured/${yyyy}/${mm}/${dd}`; + const result = await makeRestRequest(path, true); + return result; + } catch (error) { + throw new fcError(error); + } +} + /** * Returns a random page * diff --git a/source/optionTypes.ts b/source/optionTypes.ts index 5d0952b..3747fb3 100644 --- a/source/optionTypes.ts +++ b/source/optionTypes.ts @@ -31,6 +31,12 @@ export interface eventOptions { day?: string } +export interface fcOptions { + year?: string, + month?: string, + day?: string +} + export type eventTypes = 'all' | 'selected' | 'births' | 'deaths' | 'events' | 'holidays' diff --git a/source/resultTypes.ts b/source/resultTypes.ts index 0f9a2ab..062842d 100644 --- a/source/resultTypes.ts +++ b/source/resultTypes.ts @@ -106,6 +106,17 @@ export interface wikiSummary { } } +export interface MostRead extends wikiSummary { + views: number; + rank: number; + view_history: [ + { + date: string; + views: number; + } + ] +} + export interface wikiMediaResult { revision: string, tid: string, @@ -239,6 +250,15 @@ export interface htmlText { text: string } +export interface Artist extends htmlText { + name: string; + user_page?: string; +} + +export interface Description extends htmlText { + lang: string; +} + export interface notFound { type: string, title: string, @@ -246,3 +266,51 @@ export interface notFound { detail: string, uri: string } + +export interface featuredContentResult { + tfa: wikiSummary; + mostread: { + date: string; + articles: Array + }; + image: { + title: string; + thumbnail: { + source: string; + width: number; + height: number; + }; + image: { + source: string; + width: number; + height: number; + }; + file_page: string; + artist: Artist; + credit: htmlText; + license: { + type: string; + code: string; + }; + description: Description; + wb_entity_id: string; + structured: { + captions: { + [key: string]: string; + } + }; + }; + news: [ + { + links: Array; + story: string; + } + ]; + onthisday: [ + { + text: string; + pages: Array; + year: number; + } + ] +} \ No newline at end of file diff --git a/source/utils.ts b/source/utils.ts index 08a725e..33966b3 100644 --- a/source/utils.ts +++ b/source/utils.ts @@ -40,6 +40,13 @@ export function setPageId(params: any, results: any): number { return pageId; } +//Get current year +export function getCurrentYear(): number { + const date = new Date(); + const year = date.getFullYear(); + return (year); +} + //Get current month export function getCurrentMonth(): number { const date = new Date(); diff --git a/test/featuredContent.test.ts b/test/featuredContent.test.ts new file mode 100644 index 0000000..cf09d6f --- /dev/null +++ b/test/featuredContent.test.ts @@ -0,0 +1,39 @@ +import { fcError } from '../source/errors'; +import * as request from '../source/request'; +import wiki from "../source/index"; +import { fcData } from './samples'; +const requestMock = jest.spyOn(request, "makeRestRequest"); + +const fcMock = fcData; + +afterAll(() => { + requestMock.mockRestore(); +}) + +test('Throws featured content error if response is error', async () => { + requestMock.mockImplementation(async () => { throw new Error("This is an error") }); + const result = async () => { + await wiki.featuredContent({}) + }; + expect(result).rejects.toThrowError(fcError); +}); + +test('Returns with results as fcResult', async () => { + requestMock.mockImplementation(async () => { return fcMock }); + const result = await wiki.featuredContent(); + expect(result).toStrictEqual(fcMock); +}); + +test('Featured content method call with params passed and no padding', async () => { + requestMock.mockImplementation(async () => { return fcMock }); + const result = await wiki.featuredContent({ year: '2020', month: '1', day: '1' }); + expect(result).toStrictEqual(fcMock); + expect(requestMock).toBeCalledWith(`feed/featured/2020/01/01`, true); +}); + +test('Featured content method call with params passed', async () => { + requestMock.mockImplementation(async () => { return fcMock }); + const result = await wiki.featuredContent({ year: '2020', month: '01', day: '01' }); + expect(result).toStrictEqual(fcMock); + expect(requestMock).toBeCalledWith(`feed/featured/2020/01/01`, true); +}); \ No newline at end of file diff --git a/test/samples.ts b/test/samples.ts index 8672988..fb655be 100644 --- a/test/samples.ts +++ b/test/samples.ts @@ -301,3 +301,122 @@ export const citationData = { } ] } + +const sampleSummary = { + "type": "standard", + "title": "Jared_Lee_Loughner", + "displaytitle": "Jared Lee Loughner", + "namespace": { + "id": 0, + "text": "" + }, + "wikibase_item": "Q4267485", + "titles": { + "canonical": "Jared_Lee_Loughner", + "normalized": "Jared Lee Loughner", + "display": "Jared Lee Loughner" + }, + "pageid": 30372228, + "thumbnail": { + "source": "https://upload.wikimedia.org/wikipedia/commons/thumb/8/82/Jared_Loughner_USMS.jpg/256px-Jared_Loughner_USMS.jpg", + "width": 256, + "height": 320 + }, + "originalimage": { + "source": "https://upload.wikimedia.org/wikipedia/commons/8/82/Jared_Loughner_USMS.jpg", + "width": 480, + "height": 600 + }, + "lang": "en", + "dir": "ltr", + "revision": "1063449101", + "tid": "fa00d540-6d07-11ec-b627-0543a4912f8c", + "timestamp": "2022-01-03T04:11:55Z", + "description": "American mass murderer", + "description_source": "local", + "content_urls": { + "desktop": { + "page": "https://en.wikipedia.org/wiki/Jared_Lee_Loughner", + "revisions": "https://en.wikipedia.org/wiki/Jared_Lee_Loughner?action=history", + "edit": "https://en.wikipedia.org/wiki/Jared_Lee_Loughner?action=edit", + "talk": "https://en.wikipedia.org/wiki/Talk:Jared_Lee_Loughner" + }, + "mobile": { + "page": "https://en.m.wikipedia.org/wiki/Jared_Lee_Loughner", + "revisions": "https://en.m.wikipedia.org/wiki/Special:History/Jared_Lee_Loughner", + "edit": "https://en.m.wikipedia.org/wiki/Jared_Lee_Loughner?action=edit", + "talk": "https://en.m.wikipedia.org/wiki/Talk:Jared_Lee_Loughner" + } + }, + "rxtract": "abc", + "extract_html": "

abc

", + "normalizedtitle": "abc" +} + +export const fcData = { + "tfa": sampleSummary, + "mostread": { + "date": "2022-01-07Z", + "articles": [ + { + "views": 1064940, + "rank": 3, + "view_history": [ + { + "date": "2022-01-07Z", + "views": 1064940 + } + ], + ...sampleSummary + }, + ] + }, + "image": { + "title": "File:1930s Japan Travel Poster - 01.jpg", + "thumbnail": { + "source": "https://upload.wikimedia.org/wikipedia/commons/thumb/5/54/1930s_Japan_Travel_Poster_-_01.jpg/640px-1930s_Japan_Travel_Poster_-_01.jpg", + "width": 640, + "height": 934 + }, + "image": { + "source": "https://upload.wikimedia.org/wikipedia/commons/5/54/1930s_Japan_Travel_Poster_-_01.jpg", + "width": 2056, + "height": 3000 + }, + "file_page": "https://commons.wikimedia.org/wiki/File:1930s_Japan_Travel_Poster_-_01.jpg", + "artist": { + "html": "Japanese Government Railways", + "text": "Japanese Government Railways", + "name": "Japanese Government Railways" + }, + "credit": { + "html": "Heritage Auctions", + "text": "Heritage Auctions" + }, + "license": { + "type": "Public domain", + "code": "pd" + }, + "description": { + "html": "Sea bathing in Obama", + "text": "Sea bathing in Obama", + "lang": "en" + }, + "wb_entity_id": "M31526367", + "structured": { + "captions": {} + } + }, + "news": [ + { + "links": [ sampleSummary ], + "story": "Bahamian-American actor." + }, + ], + "onthisday": [ + { + "text": "abc", + "pages": [ sampleSummary ] + } + ], +} \ No newline at end of file From 060b9cb4b9d0e6ec24c8cc9a82d5ff33e1998527 Mon Sep 17 00:00:00 2001 From: Kevin Kee Date: Sat, 8 Jan 2022 15:26:06 +0900 Subject: [PATCH 2/2] Add documentation for featured content resolving #34 --- docs/optionTypes.md | 15 +++++++++++++ docs/resultTypes.md | 54 +++++++++++++++++++++++++++++++++++++++++++++ docs/wiki.md | 24 ++++++++++++++++++++ 3 files changed, 93 insertions(+) diff --git a/docs/optionTypes.md b/docs/optionTypes.md index 982b2f0..5e8b125 100644 --- a/docs/optionTypes.md +++ b/docs/optionTypes.md @@ -7,6 +7,7 @@ - [searchOptions](#searchOptions) - [geoOptions](#geoOptions) - [eventOptions](#eventOptions) +- [fcOptions](#fcOptions) - [pdfOptions](#pdfOptions) ### pageOptions @@ -79,6 +80,20 @@ The options for the onThisDay function on wiki object. - `month : string`(default = date.getMonth()) - Use this to pass the month you want as a string. By default, it will take current month. - `day : string`(default = date.getDay()) - Use this to pass the day you want as a string. By default, it will take current day. +### fcOptions +```js +interface fcOptions { + year?: string, + month?: string, + day?: string +} +``` +The options for the featured content function on wiki object. + +- `year : string`(default = date.getYear()) - Use this to pass the year you want as a string. By default, it will take current year. +- `month : string`(default = date.getMonth()) - Use this to pass the month you want as a string. By default, it will take current month. +- `day : string`(default = date.getDay()) - Use this to pass the day you want as a string. By default, it will take current day. + ### pdfOptions ```js interface pdfOptions { diff --git a/docs/resultTypes.md b/docs/resultTypes.md index bf671dc..3d28ff7 100644 --- a/docs/resultTypes.md +++ b/docs/resultTypes.md @@ -11,6 +11,7 @@ - [languageResult](#languageResult) - [wikiMediaResult](#wikiMediaResult) - [eventResult](#eventResult) +- [fcResult](#fcResult) - [relatedResult](#relatedResult) - [titleItem](#titleItem) - [mobileSections](#mobileSections) @@ -211,6 +212,59 @@ interface eventResult { } ``` +### fcResult + +The result for the `featuredContent` function call. +```js +interface fcResult { + tfa: wikiSummary; + mostread: { + date: string; + articles: Array + }; + image: { + title: string; + thumbnail: { + source: string; + width: number; + height: number; + }; + image: { + source: string; + width: number; + height: number; + }; + file_page: string; + artist: Artist; + credit: htmlText; + license: { + type: string; + code: string; + }; + description: Description; + wb_entity_id: string; + structured: { + captions: { + [key: string]: string; + } + }; + }; + news: [ + { + links: Array; + story: string; + } + ]; + onthisday: [ + { + text: string; + pages: Array; + year: number; + } + ] +} +``` + ### relatedResult The related result. diff --git a/docs/wiki.md b/docs/wiki.md index b046c64..127e11b 100644 --- a/docs/wiki.md +++ b/docs/wiki.md @@ -7,6 +7,7 @@ - [page()](#page) - [geoSearch()](#geoSearch) - [onThisDay()](#onThisDay) + - [featuredContent()](#featuredContent) - [languages()](#languages) - [setLang()](#setLang) - [suggest()](#suggest) @@ -70,6 +71,28 @@ console.log(events); // returns all the events which happened today console.log(deaths); // returns all deaths which happened on Feb 28 ``` +### featuredContent() + +Returns featured content of a given day, depending on input `year`, `month`, `day` arguments. By default, it will return featured content of the current day. Returns a array of [fcResult][27] object. + +```js +featuredContent = async ({year: string, month: string, day: string}): Promise +``` +- @param year - The year to search for. Takes current year by default. +- @param month - The month to search for. Takes current month by default. +- @param day - The day to search for. Takes current day by default. +- @result [fcResult][27] - a fcResult object. + +```js +//example +const content = await wiki.featuredContent(); +const contentNewYear2020 = await wiki.featuredContent({year:'2020', month:'01', day:'01'}); +const contentNewYear = await wiki.featuredContent({month:'01', day:'01'}); +console.log(content); // returns featured content from today +console.log(contentNewYear2020); // returns featured content from 2020-01-01 +console.log(contentNewYear); // returns featured content from 01-01 of this year +``` + ### geoSearch() Searches for a page based on input `latitude`, `longitude` coordinates. Optionally takes a `limit` and `radius`(the search radius in meters) parameter in the [geoOptions][5] object. Returns an array of [geoSearchResult][6] object. @@ -210,5 +233,6 @@ console.log(html); //Returns html for the environmentalist [24]: https://github.com/dopecodez/wikipedia/blob/master/docs/resultTypes.md#eventResult [25]: https://github.com/dopecodez/wikipedia/blob/master/docs/PAGE.md#mobileHtml [26]: https://github.com/dopecodez/wikipedia/blob/master/docs/PAGE.md#pdf +[27]: https://github.com/dopecodez/wikipedia/blob/master/docs/resultTypes.md#fcResult