Skip to content

Commit

Permalink
Add news api with NPR and Al Jazeera test sources
Browse files Browse the repository at this point in the history
  • Loading branch information
tireymorris committed Jun 22, 2024
1 parent b7e6e4e commit 2d578bc
Show file tree
Hide file tree
Showing 7 changed files with 105 additions and 17 deletions.
Binary file modified bun.lockb
Binary file not shown.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
},
"dependencies": {
"@unocss/preset-web-fonts": "^0.61.0",
"cheerio": "^1.0.0-rc.12",
"hono": "^4.4.6",
"nodemon": "^3.1.0",
"unocss": "^0.61.0",
Expand Down
9 changes: 3 additions & 6 deletions public/styles/uno.css
Original file line number Diff line number Diff line change
Expand Up @@ -43,12 +43,10 @@
.bg-gray-300{--un-bg-opacity:1;background-color:rgb(209 213 219 / var(--un-bg-opacity));}
.bg-indigo-200{--un-bg-opacity:1;background-color:rgb(199 210 254 / var(--un-bg-opacity));}
.bg-transparent{background-color:transparent;}
.bg-white,
[bg-white=""]{--un-bg-opacity:1;background-color:rgb(255 255 255 / var(--un-bg-opacity));}
.bg-white{--un-bg-opacity:1;background-color:rgb(255 255 255 / var(--un-bg-opacity));}
.dark .dark\:bg-blue-600{--un-bg-opacity:1;background-color:rgb(37 99 235 / var(--un-bg-opacity));}
.dark .dark\:bg-gray-700{--un-bg-opacity:1;background-color:rgb(55 65 81 / var(--un-bg-opacity));}
.dark .dark\:bg-gray-900,
.dark [dark\:bg-gray-900=""]{--un-bg-opacity:1;background-color:rgb(17 24 39 / var(--un-bg-opacity));}
.dark .dark\:bg-gray-900{--un-bg-opacity:1;background-color:rgb(17 24 39 / var(--un-bg-opacity));}
.dark .dark\:bg-indigo-600{--un-bg-opacity:1;background-color:rgb(79 70 229 / var(--un-bg-opacity));}
.hover\:bg-blue-400:hover{--un-bg-opacity:1;background-color:rgb(96 165 250 / var(--un-bg-opacity));}
.p-0{padding:0;}
Expand All @@ -66,8 +64,7 @@
.text-5xl{font-size:3rem;line-height:1;}
.text-base{font-size:1rem;line-height:1.5rem;}
.text-sm{font-size:0.875rem;line-height:1.25rem;}
.dark .dark\:text-white,
.dark [dark\:text-white=""]{--un-text-opacity:1;color:rgb(255 255 255 / var(--un-text-opacity));}
.dark .dark\:text-white{--un-text-opacity:1;color:rgb(255 255 255 / var(--un-text-opacity));}
.text-black{--un-text-opacity:1;color:rgb(0 0 0 / var(--un-text-opacity));}
.text-neutral-500{--un-text-opacity:1;color:rgb(115 115 115 / var(--un-text-opacity));}
.text-slate-900{--un-text-opacity:1;color:rgb(15 23 42 / var(--un-text-opacity));}
Expand Down
69 changes: 69 additions & 0 deletions src/util/api.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
import { load } from "cheerio";
import { z } from "zod";

const articleSchema = z.object({
title: z.string().min(5),
link: z.string().url(),
source: z.string(),
});

type NewsSource = {
name: string;
url: (page: number) => string;
listSelector: string;
baseUrl?: string;
};

const newsSources: NewsSource[] = [
{
name: "NPR",
url: (page: number) => `http://text.npr.org?page=${page}`,
listSelector: "ul > li > a",
baseUrl: "http://text.npr.org",
},
{
name: "Al Jazeera",
url: (page: number) => `https://www.aljazeera.com/us-canada?page=${page}`,
listSelector: "article .gc__content a",
baseUrl: "https://www.aljazeera.com",
},
];

const isValidArticle = (article: { title: string; link: string }) => {
try {
articleSchema.parse(article);
return true;
} catch (e) {
return false;
}
};

const fetchArticlesFromSource = async (
source: NewsSource,
page: number = 1,
) => {
const response = await fetch(source.url(page));
const text = await response.text();

const $ = load(text);
const articles: { title: string; link: string; source: string }[] = [];

$(source.listSelector).each((_, element) => {
const title = $(element).text().trim();
const link = source.baseUrl
? `${source.baseUrl}${$(element).attr("href")}`
: $(element).attr("href");

if (title && link) {
articles.push({
title,
link,
source: source.name,
});
}
});

return articles.filter(isValidArticle);
};

export { fetchArticlesFromSource, isValidArticle, newsSources };
28 changes: 28 additions & 0 deletions test/api.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { describe, expect, it } from "bun:test";
import { fetchArticlesFromSource, newsSources } from "../src/util/api";

describe("Article Fetching Functions", () => {
it("Should fetch and parse NPR articles", async () => {
const articles = await fetchArticlesFromSource(newsSources[0], 1);
expect(articles.length).toBeGreaterThanOrEqual(10);
articles.forEach((article) => {
expect(article).toMatchObject({
title: expect.any(String),
link: expect.any(String),
source: "NPR",
});
});
});

it("Should fetch and parse Al Jazeera articles", async () => {
const articles = await fetchArticlesFromSource(newsSources[1], 1);
expect(articles.length).toBeGreaterThanOrEqual(10);
articles.forEach((article) => {
expect(article).toMatchObject({
title: expect.any(String),
link: expect.any(String),
source: "Al Jazeera",
});
});
});
});
7 changes: 0 additions & 7 deletions test/fake.test.ts

This file was deleted.

8 changes: 4 additions & 4 deletions tsconfig.json
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
{
"compilerOptions": {
"compilerOptions": {
"jsx": "react-jsx",
"jsxImportSource": "hono/jsx",
"allowImportingTsExtensions": true,
"noEmit": true,
"types": [
"bun-types"
]
"types": ["bun-types"],
"esModuleInterop": true,
"moduleResolution": "node"
}
}

0 comments on commit 2d578bc

Please sign in to comment.