Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement method for mobile-html #17

Merged
merged 6 commits into from
Apr 22, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions docs/PAGE.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
- [coordinates()](#coordinates)
- [references()](#references)
- [langLinks()](#langLinks)
- [mobileHtml()](#mobileHtml)

## Class Members

Expand Down Expand Up @@ -273,6 +274,26 @@ const page = await wiki.page('Batman');
const tables = await page.tables({redirect: false});
```


### mobileHtml()

Returns mobile-optimised HTML for a wiki page, given a title. Follows redirects by default.

```js
mobileHtml = async (title: string, redirect?: boolean): Promise<notFound | string>
```
- @param title - the title of the page to query
- @param redirect - whether to redirect in case of 302

```js
const htmlJohnLocke = mobileHtml("John_Locke");
console.log(htmlJohnLocke); // displays HTML for John Locke's wiki page
const htmlDiscoStu = mobileHtml("Disco_Stu");
console.log(htmlDiscoStu); // redirects to List of recurring The Simpsons characters
const htmlDiscoStuNoRedirect = mobileHtml("Disco_Stu", false);
console.log(htmlDiscoStuNoRedirect); // no result, as redirect is false
```

[1]: https://github.com/dopecodez/wikipedia/blob/master/docs/optionTypes.md#pageOptions
[2]: https://github.com/dopecodez/wikipedia/blob/master/docs/resultTypes.md#wikiSummary
[3]: https://github.com/dopecodez/wikipedia/blob/master/docs/optionTypes.md#listOptions
Expand Down
3 changes: 2 additions & 1 deletion docs/wiki.md
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ console.log(randomMobileSections); // Returns random mobile sections for a page

### Page Methods

All the methods defined in the [Page][4] documentation can be called directly from the wiki object as well. This includes [summary()][8], [images()][9], [intro()][10], [html()][11], [related()][12], [content()][13], [categories()][14], [links()][15], [references()][16], [coordinates()][17], [langLinks()][18], [infobox()][19], and [tables()][20].
All the methods defined in the [Page][4] documentation can be called directly from the wiki object as well. This includes [summary()][8], [images()][9], [intro()][10], [html()][11], [related()][12], [content()][13], [categories()][14], [links()][15], [references()][16], [coordinates()][17], [langLinks()][18], [infobox()][19], [mobileHtml()](25) and [tables()][20].

**Read up [here][21] to understand when you should use these methods directly and when you should use the page methods**.
Also, note that if called directly from the wiki object, you can use the `autoSuggest` option present in the [pageOptions][3] object which will be ignored if called through page.
Expand Down Expand Up @@ -188,5 +188,6 @@ console.log(html); //Returns html for the environmentalist
[22]: https://github.com/dopecodez/wikipedia/blob/master/docs/resultTypes.md#wikiSummary
[23]: https://github.com/dopecodez/wikipedia/blob/master/docs/optionTypes.md#eventOptions
[24]: https://github.com/dopecodez/wikipedia/blob/master/docs/resultTypes.md#eventResult
[25]: https://github.com/dopecodez/wikipedia/blob/master/docs/PAGE.md#mobileHtml


24 changes: 22 additions & 2 deletions source/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@ import request, { makeRestRequest, setAPIUrl } from './request'
import { pageOptions, searchOptions, geoOptions, listOptions, eventOptions, randomFormats } from './optionTypes';
import Page, {
intro, images, html, content, categories, links, coordinates, langLinks,
references, infobox, tables, summary, related, media
references, infobox, tables, summary, related, media, mobileHtml
} from './page';
import { coordinatesResult, eventResult, geoSearchResult, imageResult, langLinksResult, languageResult,
mobileSections, relatedResult,
title, wikiMediaResult, wikiSearchResult, wikiSummary } from './resultTypes';
title, wikiMediaResult, wikiSearchResult, wikiSummary, notFound } from './resultTypes';
import {
categoriesError,
contentError, coordinatesError, eventsError, geoSearchError, htmlError, imageError, infoboxError,
Expand Down Expand Up @@ -546,6 +546,26 @@ wiki.random = async (format?: randomFormats): Promise<wikiSummary | title | rela
}
}

/**
* Returns mobile-optimised HTML of a page
*
* @param title - The title of the page to query
* @param pageOptions - Whether to redirect in case of 302
* @returns Returns HTML string
*/

wiki.mobileHtml = async (title: string, pageOptions?: pageOptions): Promise<notFound | string> => {
try {
if (pageOptions?.autoSuggest) {
title = await setTitleForPage(title);
}
const result = await mobileHtml(title, pageOptions?.redirect);
return result;
} catch (error) {
throw new htmlError(error);
}
}

export default wiki;
// For CommonJS default export support
module.exports = wiki;
Expand Down
39 changes: 38 additions & 1 deletion source/page.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { categoriesError, contentError, coordinatesError, htmlError, imageError,
infoboxError, introError, linksError, mediaError, preloadError, relatedError, summaryError } from './errors';
import request, { makeRestRequest } from './request';
import { coordinatesResult, imageResult, langLinksResult, pageResult, relatedResult, wikiMediaResult, wikiSummary } from './resultTypes';
import { coordinatesResult, imageResult, langLinksResult, notFound, pageResult, relatedResult, wikiMediaResult, wikiSummary } from './resultTypes';
import { setPageId, setPageIdOrTitleParam } from './utils';
import { listOptions, pageOptions } from './optionTypes';
import { MSGS } from './messages';
Expand Down Expand Up @@ -40,6 +40,7 @@ export class Page {
_intro!: string;
_related!: relatedResult;
_media!: wikiMediaResult;
_mobileHtml!: string | notFound;
constructor(response: pageResult) {
this.pageid = response.pageid;
this.ns = response.ns;
Expand Down Expand Up @@ -374,6 +375,25 @@ export class Page {
}
}

/**
* Returns mobile-optimised HTML of a page
*
* @param title - The title of the page to query
* @param redirect - Whether to redirect in case of 302
* @returns Returns HTML string
*/
public mobileHtml = async (pageOptions?: pageOptions): Promise<notFound | string> => {
try {
if (!this._mobileHtml) {
const result = await mobileHtml(this.title, pageOptions?.redirect);
this._mobileHtml = result;
}
return this._mobileHtml;
} catch (error) {
throw new htmlError(error);
}
}

public async runMethod(functionName: string): Promise<any> {
try {
const result = await eval(`this.${functionName}()`);
Expand Down Expand Up @@ -786,4 +806,21 @@ export const media = async (title: string, redirect = true): Promise<wikiMediaRe
}
}

/**
* Returns mobile-optimised HTML of a page
*
* @param title - The title of the page to query
* @param redirect - Whether to redirect in case of 302
* @returns Returns HTML string
*/
export const mobileHtml = async (title: string, redirect = true): Promise<notFound | string> => {
try {
const path = `page/mobile-html/${title}`;
const result = await makeRestRequest(path, redirect);
return result;
} catch (error) {
throw new htmlError(error);
}
}

export default Page;
10 changes: 8 additions & 2 deletions source/request.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,14 @@ export async function makeRestRequest(path: string, redirect = true): Promise<an
}
}
const response = await fetch(encodeURI(REST_API_URL + path), options);
const result = await response.json();
return result;

let result = await response.text();
try {
result = JSON.parse(result);
}
finally {
return result;
}
} catch (error) {
throw new wikiError(error);
}
Expand Down
10 changes: 9 additions & 1 deletion source/resultTypes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -237,4 +237,12 @@ export interface section {
export interface htmlText {
html: string,
text: string
}
}

export interface notFound {
type: string,
title: string,
method: string,
detail: string,
uri: string
}
84 changes: 84 additions & 0 deletions test/mobileHtml.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
import * as request from '../source/request';
import wiki from "../source/index";
import { htmlString, notFoundJson } from './samples';
import { htmlError } from '../source/errors';
import Page, { mobileHtml } from '../source/page';
import { pageJson } from './samples';
import * as utils from '../source/utils'
const requestMock = jest.spyOn(request, "makeRestRequest");
const setTitleMock = jest.spyOn(utils, "setTitleForPage");

const htmlResult = "<html></html>"

afterAll(() => {
requestMock.mockRestore();
setTitleMock.mockRestore();
});

test('mobilehtml method on page object returns without calling request if _mobileHtml field set', async () => {
requestMock.mockImplementation(async () => { return htmlResult });
const page = new Page(pageJson);
page._mobileHtml = htmlResult;
const result = await page.mobileHtml();
expect(requestMock).toHaveBeenCalledTimes(0);
expect(result).toStrictEqual(page._mobileHtml);
});

test('mobilehtml method on page object returns html', async () => {
requestMock.mockImplementation(async () => { return htmlResult });
const page = new Page(pageJson);
const result = await page.mobileHtml({redirect: true});
expect(requestMock).toHaveBeenCalledTimes(1);
expect(result).toStrictEqual(htmlResult);
});

test('mobilehtml method on page throws html error if response is empty', async () => {
requestMock.mockImplementation(async () => { throw new Error("This is an error") });
const page = new Page(pageJson);
const t = async () => {
await page.mobileHtml();
};
expect(t).rejects.toThrowError(htmlError);
});

test('Throws mobilehtml error if response is empty', async () => {
requestMock.mockImplementation(async () => { throw new Error("This is an error") });
const t = async () => {
await mobileHtml("Test")
};
expect(t).rejects.toThrowError(htmlError);
});

test('Returns with results as string', async () => {
requestMock.mockImplementation(async () => { return htmlResult });
const result = await mobileHtml("Test");
expect(result).toStrictEqual(htmlResult);
});

test('Returns mobilehtml when page successfully queried', async () => {
requestMock.mockImplementation(async () => { return htmlString });
const result = await wiki.mobileHtml("ACID");
expect(result).toStrictEqual(htmlString);
});

test('throws htmlError if error response', async () => {
requestMock.mockImplementation(async () => { throw new Error("This is an error") });
const t = async () => {
await wiki.mobileHtml("ACID");
};
expect(t).rejects.toThrowError(htmlError);
});

test('Returns notFound if page not found', async () => {
requestMock.mockImplementation(async () => { return notFoundJson });
const result = await wiki.mobileHtml("does-not-exist-on-wikipedia");
expect(result).toEqual(notFoundJson);
});

test('Returns empty body on redirect page with redirect set to false', async () => {
requestMock.mockImplementation(async () => { return null });
setTitleMock.mockImplementation(async () => { return "homestar" });
const result = await wiki.mobileHtml("homestar", { autoSuggest: true, redirect: false });
expect(setTitleMock).toHaveBeenCalledTimes(1);
expect(result).toBeNull();
});
10 changes: 10 additions & 0 deletions test/samples.ts
Original file line number Diff line number Diff line change
Expand Up @@ -237,3 +237,13 @@ export const title = {
}
]
}

export const notFoundJson = {
type: "https://mediawiki.org/wiki/HyperSwitch/errors/not_found",
title: "Not found.",
method: "get",
detail: "Page or revision not found.",
uri: "/en.wikipedia.org/v1/page/mobile-html/does-not-exist-on-wikipedia"
}

export const htmlString = "<!DOCTYPE html><html>abcde</html>";