From c56f59b93fc77677ec218021d1b57dda147da88f Mon Sep 17 00:00:00 2001 From: Leandro Facchinetti Date: Wed, 18 Mar 2020 15:21:44 -0400 Subject: [PATCH] . --- package-lock.json | 118 +++++++++++++++++++++++++++++++++++++++++++++ package.json | 2 + src/components.tsx | 9 ++++ src/server.tsx | 23 +++------ src/test.ts | 9 ++++ 5 files changed, 146 insertions(+), 15 deletions(-) create mode 100644 src/test.ts diff --git a/package-lock.json b/package-lock.json index 152c41c..980a2df 100644 --- a/package-lock.json +++ b/package-lock.json @@ -796,6 +796,12 @@ "@types/node": "*" } }, + "@types/cookiejar": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@types/cookiejar/-/cookiejar-2.1.1.tgz", + "integrity": "sha512-aRnpPa7ysx3aNW60hTiCtLHlQaIFsXFCgQlpakNgDNVFzbtusSY8PwjAQgRWfSk0ekNoBjO51eQRB6upA9uuyw==", + "dev": true + }, "@types/express": { "version": "4.17.3", "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.3.tgz", @@ -911,6 +917,25 @@ "integrity": "sha512-l42BggppR6zLmpfU6fq9HEa2oGPEI8yrSPL3GITjfRInppYFahObbIQOQK3UGxEnyQpltZLaPe75046NOZQikw==", "dev": true }, + "@types/superagent": { + "version": "4.1.7", + "resolved": "https://registry.npmjs.org/@types/superagent/-/superagent-4.1.7.tgz", + "integrity": "sha512-JSwNPgRYjIC4pIeOqLwWwfGj6iP1n5NE6kNBEbGx2V8H78xCPwx7QpNp9plaI30+W3cFEzJO7BIIsXE+dbtaGg==", + "dev": true, + "requires": { + "@types/cookiejar": "*", + "@types/node": "*" + } + }, + "@types/supertest": { + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/@types/supertest/-/supertest-2.0.8.tgz", + "integrity": "sha512-wcax7/ip4XSSJRLbNzEIUVy2xjcBIZZAuSd2vtltQfRK7kxhx5WMHbLHkYdxN3wuQCrwpYrg86/9byDjPXoGMA==", + "dev": true, + "requires": { + "@types/superagent": "*" + } + }, "@types/xml2js": { "version": "0.4.5", "resolved": "https://registry.npmjs.org/@types/xml2js/-/xml2js-0.4.5.tgz", @@ -1817,6 +1842,12 @@ "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=" }, + "cookiejar": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/cookiejar/-/cookiejar-2.1.2.tgz", + "integrity": "sha512-Mw+adcfzPxcPeI+0WlvRrr/3lGVO0bD75SxX6811cxSh1Wbxx7xZBGK1eVtDf6si8rg2lhnUjsVLMFMfbRIuwA==", + "dev": true + }, "copy-descriptor": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", @@ -2495,6 +2526,12 @@ "mime-types": "^2.1.12" } }, + "formidable": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/formidable/-/formidable-1.2.2.tgz", + "integrity": "sha512-V8gLm+41I/8kguQ4/o1D3RIHRmhYFG4pnNyonvua+40rqcEmT4+V71yaZ3B457xbbgCsCfjSPi65u/W6vK1U5Q==", + "dev": true + }, "forwarded": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz", @@ -5327,6 +5364,12 @@ } } }, + "process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", + "dev": true + }, "prompts": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.3.1.tgz", @@ -5460,6 +5503,21 @@ "pify": "^3.0.0" } }, + "readable-stream": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, "readdirp": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.3.0.tgz", @@ -6335,6 +6393,15 @@ "function-bind": "^1.1.1" } }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "requires": { + "safe-buffer": "~5.1.0" + } + }, "strip-ansi": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", @@ -6368,6 +6435,51 @@ "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", "dev": true }, + "superagent": { + "version": "3.8.3", + "resolved": "https://registry.npmjs.org/superagent/-/superagent-3.8.3.tgz", + "integrity": "sha512-GLQtLMCoEIK4eDv6OGtkOoSMt3D+oq0y3dsxMuYuDvaNUvuT8eFBuLmfR0iYYzHC1e8hpzC6ZsxbuP6DIalMFA==", + "dev": true, + "requires": { + "component-emitter": "^1.2.0", + "cookiejar": "^2.1.0", + "debug": "^3.1.0", + "extend": "^3.0.0", + "form-data": "^2.3.1", + "formidable": "^1.2.0", + "methods": "^1.1.1", + "mime": "^1.4.1", + "qs": "^6.5.1", + "readable-stream": "^2.3.5" + }, + "dependencies": { + "debug": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", + "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + } + } + }, + "supertest": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/supertest/-/supertest-4.0.2.tgz", + "integrity": "sha512-1BAbvrOZsGA3YTCWqbmh14L0YEq0EGICX/nBnfkfVJn7SrxQV1I3pMYjSzG9y/7ZU2V9dWqyqk2POwxlb09duQ==", + "dev": true, + "requires": { + "methods": "^1.1.2", + "superagent": "^3.8.3" + } + }, "supports-color": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", @@ -6748,6 +6860,12 @@ "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==", "dev": true }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", + "dev": true + }, "util.promisify": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/util.promisify/-/util.promisify-1.0.1.tgz", diff --git a/package.json b/package.json index e4480e4..001c6c3 100644 --- a/package.json +++ b/package.json @@ -16,11 +16,13 @@ "@types/node": "^13.9.1", "@types/react": "^16.9.23", "@types/react-dom": "^16.9.5", + "@types/supertest": "^2.0.8", "@types/xml2js": "^0.4.5", "concurrently": "^5.1.0", "jest": "^25.1.0", "nodemon": "^2.0.2", "prettier": "^1.19.1", + "supertest": "^4.0.2", "typescript": "^3.8.3" }, "jest": { diff --git a/src/components.tsx b/src/components.tsx index f677283..514186f 100644 --- a/src/components.tsx +++ b/src/components.tsx @@ -1,5 +1,6 @@ import React from "react"; import ReactDOMServer from "react-dom/server"; +import { Builder } from "xml2js"; import cryptoRandomString from "crypto-random-string"; export type Inbox = { @@ -198,3 +199,11 @@ export function feedEmail(token: string) { export function id(token: string) { return `urn:kill-the-newsletter:${token}`; } + +export function renderHtml(component: React.ReactElement): string { + return `\n${ReactDOMServer.renderToStaticMarkup(component)}`; +} + +export function renderXml(xml: object): string { + return new Builder().buildObject(xml); +} diff --git a/src/server.tsx b/src/server.tsx index d86f5e6..b9c4b0a 100644 --- a/src/server.tsx +++ b/src/server.tsx @@ -1,6 +1,5 @@ import express from "express"; import React from "react"; -import ReactDOMServer from "react-dom/server"; import { Inbox, Layout, @@ -8,19 +7,20 @@ import { Created, Feed, newToken, - feedPath + feedPath, + renderHtml, + renderXml } from "./components"; -import { Builder } from "xml2js"; import fs from "fs"; -const app = express(); +export const app = express(); app.use(express.static("static")); app.use(express.urlencoded()); app.get("/", (req, res) => res.send( - render( + renderHtml(
@@ -30,12 +30,9 @@ app.get("/", (req, res) => app.post("/", (req, res) => { const inbox: Inbox = { name: req.body.name, token: newToken() }; - fs.writeFileSync( - feedPath(inbox.token), - new Builder().buildObject(Feed(inbox)) - ); + fs.writeFileSync(feedPath(inbox.token), renderXml(Feed(inbox))); res.send( - render( + renderHtml( @@ -43,8 +40,4 @@ app.post("/", (req, res) => { ); }); -app.listen(8000); - -function render(component: React.ReactElement): string { - return `\n${ReactDOMServer.renderToStaticMarkup(component)}`; -} +if (require.main === module) app.listen(8000); diff --git a/src/test.ts b/src/test.ts new file mode 100644 index 0000000..3ce57fe --- /dev/null +++ b/src/test.ts @@ -0,0 +1,9 @@ +import { app } from "./server"; +import request from "supertest"; + +test("create feed", async () => { + const response = await request(app) + .post("/") + .send({ name: "My Feed" }); + JSON.stringify(response, null, 2); +});