-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 7df8330
Showing
25 changed files
with
11,232 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
root = true | ||
|
||
[*] | ||
end_of_line = lf | ||
trim_trailing_whitespace = true | ||
insert_final_newline = true | ||
charset = utf-8 | ||
indent_style = tab | ||
indent_size = 2 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
version: 2 | ||
updates: | ||
- package-ecosystem: github-actions | ||
directory: / | ||
schedule: | ||
interval: daily | ||
- package-ecosystem: npm | ||
directory: web | ||
schedule: | ||
interval: daily |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
name: Continuous Integration | ||
|
||
on: | ||
workflow_dispatch: | ||
push: | ||
branches: | ||
- master | ||
tags: | ||
- '*' | ||
pull_request: | ||
types: | ||
- opened | ||
- reopened | ||
- synchronize | ||
- ready_for_review | ||
|
||
concurrency: | ||
group: '${{ github.workflow }}-${{ !contains(github.event.pull_request.labels.*.name, ''ci-test-flaky'') && github.head_ref || github.run_id }}' | ||
cancel-in-progress: true | ||
|
||
jobs: | ||
ci: | ||
timeout-minutes: 2 | ||
runs-on: ubuntu-22.04 | ||
steps: | ||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 | ||
- uses: actions/setup-node@b39b52d1213e96004bfcb1c61a8a6fa8ab84f3e8 # v4.0.1 | ||
with: | ||
node-version-file: '.node-version' | ||
cache: 'npm' | ||
- name: Install npm dependencies | ||
run: npm ci | ||
- name: Build and test | ||
run: npm run ci |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
.idea | ||
*.iml | ||
node_modules | ||
dist | ||
cf/.wrangler |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
21.6.1 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
{ | ||
"$schema": "https://biomejs.dev/schemas/1.5.1/schema.json", | ||
"organizeImports": { | ||
"enabled": true | ||
}, | ||
"linter": { | ||
"enabled": true, | ||
"rules": { | ||
"recommended": true | ||
} | ||
}, | ||
"files": { | ||
"include": ["cf/*.ts", "lib/*.ts", "testdata/*.parsed.json", "testdata/*.pretty.json"], | ||
"ignore": ["cf/.wrangler"] | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
BASE_URL=https://test.dev/ | ||
RAI_BASE_URL=http://localhost:8091/ | ||
FETCH_QUEUE_SIZE=5 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
{ | ||
"$schema": "https://json.schemastore.org/tsconfig", | ||
"extends": "@tsconfig/node21/tsconfig.json", | ||
"compilerOptions": { | ||
"module": "nodenext", | ||
"noEmit": true, | ||
"resolveJsonModule": true, | ||
"types": ["@cloudflare/workers-types"] | ||
}, | ||
"include": ["*.ts", "../lib/declarations.d.ts"] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,204 @@ | ||
import { Server, createServer } from "http"; | ||
import { strict as assert } from "node:assert"; | ||
import { readFile } from "node:fs/promises"; | ||
import path from "node:path"; | ||
import test, { after, before } from "node:test"; | ||
import { fileURLToPath } from "node:url"; | ||
import { getPodcastFromFeed } from "@podverse/podcast-feed-parser"; | ||
import { createServerAdapter } from "@whatwg-node/server"; | ||
import { Router, RouterType, error, json } from "itty-router"; | ||
import { UnstableDevWorker, unstable_dev } from "wrangler"; | ||
import feedJson from "../testdata/lastoriaingiallo.json" with { type: "json" }; | ||
import expectedJson from "../testdata/lastoriaingiallo.parsed.json" with { | ||
type: "json", | ||
}; | ||
|
||
const __filename = fileURLToPath(import.meta.url); | ||
const __dirname = path.dirname(__filename); | ||
const englishHtmlPath = path.join(__dirname, "../lib/english.html"); | ||
const italianHtmlPath = path.join(__dirname, "../lib/italian.html"); | ||
|
||
let worker: UnstableDevWorker; | ||
|
||
before(async () => { | ||
const experimental = { disableExperimentalWarning: true }; | ||
worker = await unstable_dev("cf/worker.ts", { | ||
// uncomment and change level for help debugging | ||
// logLevel: "info", | ||
experimental, | ||
}); | ||
}); | ||
|
||
after(async () => { | ||
await worker.stop(); | ||
}); | ||
|
||
test("english index", async () => { | ||
const englishIndex = await readFile(englishHtmlPath, "utf8"); | ||
const resp = await worker.fetch(); | ||
const text = await resp.text(); | ||
|
||
assert(resp.ok); | ||
assert.strictEqual(resp.status, 200); | ||
assert.strictEqual(resp.statusText, "OK"); | ||
assert.strictEqual(resp.headers.get("Content-Language"), "en"); | ||
assert.strictEqual(text, englishIndex); | ||
}); | ||
|
||
test("italian index", async () => { | ||
const italianIndex = await readFile(italianHtmlPath, "utf8"); | ||
const resp = await worker.fetch("", { headers: { "Accept-Language": "it" } }); | ||
const text = await resp.text(); | ||
|
||
assert(resp.ok); | ||
assert.strictEqual(resp.status, 200); | ||
assert.strictEqual(resp.statusText, "OK"); | ||
assert.strictEqual(resp.headers.get("Content-Language"), "it"); | ||
assert.strictEqual(text, italianIndex); | ||
}); | ||
|
||
test("rss feed success", async (t) => { | ||
const router = Router(); | ||
router.get("/programmi/lastoriaingiallo.json", () => { | ||
return json(feedJson); | ||
}); | ||
router.head( | ||
"*", | ||
() => | ||
new Response(null, { | ||
status: 200, | ||
headers: { | ||
"Content-Type": "audio/mpeg", | ||
"Content-Length": "123456789", | ||
}, | ||
}), | ||
); | ||
await using _server = await MockRaiServer.create(router); | ||
|
||
const resp = await worker.fetch("/programmi/lastoriaingiallo.xml"); | ||
assert(resp.ok); | ||
assert.strictEqual(resp.status, 200); | ||
|
||
const feed = await resp.text(); | ||
const parsedFeed = JSON.parse(JSON.stringify(getPodcastFromFeed(feed))); | ||
|
||
const trulyExpectedJSON = replaceImageUrls( | ||
replaceMediaUrls(stripLastBuildDate(expectedJson)), | ||
); | ||
trulyExpectedJSON.meta.imageURL = trulyExpectedJSON.meta.imageURL.replace( | ||
/^https:\/\/test.dev\//, | ||
"http://localhost:8091/", | ||
); | ||
assert.deepStrictEqual(stripLastBuildDate(parsedFeed), trulyExpectedJSON); | ||
}); | ||
|
||
test("rss feed failure: 404 from RAI server", async () => { | ||
const resp = await worker.fetch("/theserverisntevenrunning.xml"); | ||
assert(!resp.ok); | ||
assert.strictEqual(resp.status, 404); | ||
}); | ||
|
||
test("rss feed failure: 500 from RAI server", async () => { | ||
const router = Router(); | ||
router.get("/programmi/500.json", () => { | ||
return error(500, "RAI server exploded"); | ||
}); | ||
await using _ = await MockRaiServer.create(router); | ||
|
||
const resp = await worker.fetch("/programmi/500.xml"); | ||
assert(!resp.ok); | ||
assert.strictEqual(resp.status, 500); | ||
}); | ||
|
||
test("rss feed failure: failure to process RAI json feed", async () => { | ||
const router = Router(); | ||
router.get("/programmi/lastoriaingiallo.json", () => { | ||
return json({ foo: "bar" }); | ||
}); | ||
await using _server = await MockRaiServer.create(router); | ||
|
||
const resp = await worker.fetch("/programmi/lastoriaingiallo.xml"); | ||
assert(!resp.ok); | ||
assert.strictEqual(resp.status, 500); | ||
assert.strictEqual(resp.statusText, "Internal Server Error"); | ||
const text = await resp.text(); | ||
assert.strictEqual( | ||
text, | ||
'{"status":500,"error":"error converting upstream json feed from RAI"}', | ||
); | ||
}); | ||
|
||
test("404", async () => { | ||
const resp = await worker.fetch("foo"); | ||
|
||
assert(!resp.ok); | ||
assert.strictEqual(resp.status, 404); | ||
assert.strictEqual(resp.statusText, "Not Found"); | ||
const text = await resp.text(); | ||
assert.strictEqual(text, "Not found."); | ||
}); | ||
|
||
class MockRaiServer { | ||
#server: Server; | ||
|
||
private constructor(server: Server) { | ||
this.#server = server; | ||
} | ||
|
||
static async create(router: RouterType): Promise<MockRaiServer> { | ||
const { RAI_BASE_URL } = process.env; | ||
if (RAI_BASE_URL === undefined) { | ||
throw new Error("RAI_BASE_URL is undefined"); | ||
} | ||
const url = new URL(RAI_BASE_URL); | ||
const listenPort = parseInt(url.port); | ||
|
||
const ittyServer = createServerAdapter(router); | ||
const httpServer = createServer(ittyServer); | ||
await new Promise<void>((resolve) => | ||
httpServer.listen(listenPort, url.hostname, resolve), | ||
); | ||
return new MockRaiServer(httpServer); | ||
} | ||
|
||
[Symbol.asyncDispose](): Promise<void> { | ||
return this.#server[Symbol.asyncDispose](); | ||
} | ||
} | ||
|
||
type ExpectedJson = typeof expectedJson; | ||
type DatelessMeta = Omit<typeof expectedJson.meta, "lastBuildDate">; | ||
type ExpectedJsonWithoutBuildDate = Omit<ExpectedJson, "meta"> & { | ||
meta: DatelessMeta; | ||
}; | ||
function stripLastBuildDate({ | ||
meta, | ||
...rest | ||
}: ExpectedJson): ExpectedJsonWithoutBuildDate { | ||
const { lastBuildDate, ...metaRest } = meta; | ||
return { meta: metaRest, ...rest }; | ||
} | ||
|
||
function replaceMediaUrls( | ||
j: ExpectedJsonWithoutBuildDate, | ||
): ExpectedJsonWithoutBuildDate { | ||
for (const e of j.episodes) { | ||
e.enclosure.url = e.enclosure.url.replace( | ||
/^https:\/\/media.test.dev\/(.+)\.mp3$/, | ||
(_, p1) => | ||
`http://localhost:8091/relinker/relinkerServlet.htm?cont=${p1}`, | ||
); | ||
} | ||
return j; | ||
} | ||
function replaceImageUrls( | ||
j: ExpectedJsonWithoutBuildDate, | ||
): ExpectedJsonWithoutBuildDate { | ||
for (const e of j.episodes) { | ||
e.imageURL = e.imageURL.replace( | ||
/^https:\/\/test.dev\//, | ||
"http://localhost:8091/", | ||
); | ||
} | ||
return j; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
import { Env, fetchHandler } from "../lib/router.js"; | ||
|
||
export default (<ExportedHandler<Env>>{ | ||
fetch: (request, env, _ctx) => fetchHandler(request, env), | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
name = "raiplayrss" | ||
main = "./worker.ts" | ||
compatibility_date = "2024-01-16" | ||
node_compat = true | ||
|
||
[env.prod.vars] | ||
BASE_URL = "https://raiplayrss.workers.dev/" | ||
RAI_BASE_URL = "https://www.raiplaysound.it/" | ||
FETCH_QUEUE_SIZE = 5 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
declare module "*.html" { | ||
const content: string; | ||
export default content; | ||
} | ||
|
||
declare module "@podverse/podcast-feed-parser"; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
<!DOCTYPE html> | ||
<html lang="en"> | ||
<head> | ||
<meta charset="UTF-8"> | ||
<meta name="viewport" content="width=device-width, initial-scale=1.0"> | ||
<title>raiplayrss</title> | ||
</head> | ||
<body> | ||
<h1>raiplayrss</h1> | ||
<p>having some fun</p> | ||
</body> | ||
</html> |
Oops, something went wrong.