Commit 22112c76 authored by Brendan Wong's avatar Brendan Wong Committed by GitHub

feat: automated testing for cloud functions (#6931)

* feat: add token and nft injection

* feat: basic tests

* fix: get jest configured properly

* fix: change timeout

* fix: uninstall port ready

* fix: readd port ready

* fix: local tests work

* Update yarn.lock

* add lint disable for setup files

* fix: update dependencies

* fix: basic test suite for nfts/tokens

* feat: collection data

* fix: make tests more comprehensive

* fix: change matches to contains

* fix: tests for twitter alt image tag

* fix: image gen

* fix: add patch-package

* fix: update yarn install

* feat: basic image gen for nfts and collections

* fix: remove vibrant attempt

* use watermark asset

* dynamically grab color

* modularize code and prototype for token preview

* refactor code

* finalize css

* fix color grabber

* update tests

* fix up css

* refactor code a bit more

* remove console logs

* tests

* update tests

* update images based on design feedback

* network logos

* update lint

* slight refactoring

* more refactoring

* fix packages

* Update yarn.lock

* remove dynamically generated image stuff

* cleanup return values

* Create README.md

* Revert "Create README.md"

This reverts commit 7a91c98d384995fba914c9bf9a2fb3072793621f.

* First round of feedback

* comments

* Update test.yml

* Update test.yml

* Update test.yml

* feedback round 2

* final feedback

* final final feedback

* add coverage and other options

* Update test.yml

* start typecheck

* update cache

* update snapshots?

* Update jest.config.json

* Update jest.config.json

* give timeout some buffer

* update import

* upgrade ts

* fix typing for apollo deps

* finalize typechecks

* downgrade typescript to original version

* add cache directory to jest

* remove coverage

* remove google analytics from tests

* review changes
parent b230cb62
...@@ -169,6 +169,41 @@ jobs: ...@@ -169,6 +169,41 @@ jobs:
name: Cypress tests name: Cypress tests
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_TEST_REPORTER_WEBHOOK }} SLACK_WEBHOOK_URL: ${{ secrets.SLACK_TEST_REPORTER_WEBHOOK }}
cloud-typecheck:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: ./.github/actions/setup
- uses: ./.github/actions/cache-on-main
with:
path: node_modules/.cache
key: ${{ runner.os }}-cloud-tsc-${{ github.run_id }}
restore-keys: ${{ runner.os }}-cloud-tsc-
- run: yarn typecheck:cloud
- if: failure() && github.ref_name == 'main'
uses: ./.github/actions/report
with:
name: Cloud typecheck
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_TEST_REPORTER_WEBHOOK }}
# TODO(WEB-2537): Setup CodeCOV
cloud-tests:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: ./.github/actions/setup
- uses: ./.github/actions/cache-on-main
with:
path: node_modules/.cache
key: ${{ runner.os }}-cloud-jest-${{ github.run_id }}
restore-keys: ${{ runner.os }}-cloud-jest-
- run: yarn test:cloud --coverage --maxWorkers=100%
- if: failure() && github.ref_name == 'main'
uses: ./.github/actions/report
with:
name: Cloud tests
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_TEST_REPORTER_WEBHOOK }}
pre: pre:
if: ${{ github.ref_name == 'main' || github.ref_name == 'releases/staging' }} if: ${{ github.ref_name == 'main' || github.ref_name == 'releases/staging' }}
runs-on: ubuntu-latest runs-on: ubuntu-latest
......
...@@ -19,6 +19,7 @@ schema.graphql ...@@ -19,6 +19,7 @@ schema.graphql
# testing # testing
/coverage /coverage
/cache /cache
/functions/coverage
# builds # builds
/build /build
......
...@@ -22,7 +22,7 @@ exports[`should inject metadata for valid collections 1`] = ` ...@@ -22,7 +22,7 @@ exports[`should inject metadata for valid collections 1`] = `
<meta <meta
http-equiv="Content-Security-Policy" http-equiv="Content-Security-Policy"
content="script-src 'self' https://www.google-analytics.com https://www.googletagmanager.com 'unsafe-inline'" content="script-src 'self' 'unsafe-inline'"
/> />
...@@ -38,8 +38,6 @@ exports[`should inject metadata for valid collections 1`] = ` ...@@ -38,8 +38,6 @@ exports[`should inject metadata for valid collections 1`] = `
--> -->
<link rel="manifest" href="./manifest.json" /> <link rel="manifest" href="./manifest.json" />
<link rel="preconnect" href="https://www.google-analytics.com/" />
<link rel="preload" href="./fonts/Inter-roman.var.woff2" as="font" type="font/woff2" crossorigin /> <link rel="preload" href="./fonts/Inter-roman.var.woff2" as="font" type="font/woff2" crossorigin />
<style> <style>
...@@ -156,7 +154,7 @@ exports[`should inject metadata for valid collections 2`] = ` ...@@ -156,7 +154,7 @@ exports[`should inject metadata for valid collections 2`] = `
<meta <meta
http-equiv="Content-Security-Policy" http-equiv="Content-Security-Policy"
content="script-src 'self' https://www.google-analytics.com https://www.googletagmanager.com 'unsafe-inline'" content="script-src 'self' 'unsafe-inline'"
/> />
...@@ -172,8 +170,6 @@ exports[`should inject metadata for valid collections 2`] = ` ...@@ -172,8 +170,6 @@ exports[`should inject metadata for valid collections 2`] = `
--> -->
<link rel="manifest" href="./manifest.json" /> <link rel="manifest" href="./manifest.json" />
<link rel="preconnect" href="https://www.google-analytics.com/" />
<link rel="preload" href="./fonts/Inter-roman.var.woff2" as="font" type="font/woff2" crossorigin /> <link rel="preload" href="./fonts/Inter-roman.var.woff2" as="font" type="font/woff2" crossorigin />
<style> <style>
...@@ -290,7 +286,7 @@ exports[`should inject metadata for valid collections 3`] = ` ...@@ -290,7 +286,7 @@ exports[`should inject metadata for valid collections 3`] = `
<meta <meta
http-equiv="Content-Security-Policy" http-equiv="Content-Security-Policy"
content="script-src 'self' https://www.google-analytics.com https://www.googletagmanager.com 'unsafe-inline'" content="script-src 'self' 'unsafe-inline'"
/> />
...@@ -306,8 +302,6 @@ exports[`should inject metadata for valid collections 3`] = ` ...@@ -306,8 +302,6 @@ exports[`should inject metadata for valid collections 3`] = `
--> -->
<link rel="manifest" href="./manifest.json" /> <link rel="manifest" href="./manifest.json" />
<link rel="preconnect" href="https://www.google-analytics.com/" />
<link rel="preload" href="./fonts/Inter-roman.var.woff2" as="font" type="font/woff2" crossorigin /> <link rel="preload" href="./fonts/Inter-roman.var.woff2" as="font" type="font/woff2" crossorigin />
<style> <style>
......
...@@ -22,7 +22,7 @@ exports[`should inject metadata for valid assets 1`] = ` ...@@ -22,7 +22,7 @@ exports[`should inject metadata for valid assets 1`] = `
<meta <meta
http-equiv="Content-Security-Policy" http-equiv="Content-Security-Policy"
content="script-src 'self' https://www.google-analytics.com https://www.googletagmanager.com 'unsafe-inline'" content="script-src 'self' 'unsafe-inline'"
/> />
...@@ -38,8 +38,6 @@ exports[`should inject metadata for valid assets 1`] = ` ...@@ -38,8 +38,6 @@ exports[`should inject metadata for valid assets 1`] = `
--> -->
<link rel="manifest" href="./manifest.json" /> <link rel="manifest" href="./manifest.json" />
<link rel="preconnect" href="https://www.google-analytics.com/" />
<link rel="preload" href="./fonts/Inter-roman.var.woff2" as="font" type="font/woff2" crossorigin /> <link rel="preload" href="./fonts/Inter-roman.var.woff2" as="font" type="font/woff2" crossorigin />
<style> <style>
...@@ -156,7 +154,7 @@ exports[`should inject metadata for valid assets 2`] = ` ...@@ -156,7 +154,7 @@ exports[`should inject metadata for valid assets 2`] = `
<meta <meta
http-equiv="Content-Security-Policy" http-equiv="Content-Security-Policy"
content="script-src 'self' https://www.google-analytics.com https://www.googletagmanager.com 'unsafe-inline'" content="script-src 'self' 'unsafe-inline'"
/> />
...@@ -172,8 +170,6 @@ exports[`should inject metadata for valid assets 2`] = ` ...@@ -172,8 +170,6 @@ exports[`should inject metadata for valid assets 2`] = `
--> -->
<link rel="manifest" href="./manifest.json" /> <link rel="manifest" href="./manifest.json" />
<link rel="preconnect" href="https://www.google-analytics.com/" />
<link rel="preload" href="./fonts/Inter-roman.var.woff2" as="font" type="font/woff2" crossorigin /> <link rel="preload" href="./fonts/Inter-roman.var.woff2" as="font" type="font/woff2" crossorigin />
<style> <style>
...@@ -290,7 +286,7 @@ exports[`should inject metadata for valid assets 3`] = ` ...@@ -290,7 +286,7 @@ exports[`should inject metadata for valid assets 3`] = `
<meta <meta
http-equiv="Content-Security-Policy" http-equiv="Content-Security-Policy"
content="script-src 'self' https://www.google-analytics.com https://www.googletagmanager.com 'unsafe-inline'" content="script-src 'self' 'unsafe-inline'"
/> />
...@@ -306,8 +302,6 @@ exports[`should inject metadata for valid assets 3`] = ` ...@@ -306,8 +302,6 @@ exports[`should inject metadata for valid assets 3`] = `
--> -->
<link rel="manifest" href="./manifest.json" /> <link rel="manifest" href="./manifest.json" />
<link rel="preconnect" href="https://www.google-analytics.com/" />
<link rel="preload" href="./fonts/Inter-roman.var.woff2" as="font" type="font/woff2" crossorigin /> <link rel="preload" href="./fonts/Inter-roman.var.woff2" as="font" type="font/woff2" crossorigin />
<style> <style>
......
...@@ -22,7 +22,7 @@ exports[`should inject metadata for valid tokens 1`] = ` ...@@ -22,7 +22,7 @@ exports[`should inject metadata for valid tokens 1`] = `
<meta <meta
http-equiv="Content-Security-Policy" http-equiv="Content-Security-Policy"
content="script-src 'self' https://www.google-analytics.com https://www.googletagmanager.com 'unsafe-inline'" content="script-src 'self' 'unsafe-inline'"
/> />
...@@ -38,8 +38,6 @@ exports[`should inject metadata for valid tokens 1`] = ` ...@@ -38,8 +38,6 @@ exports[`should inject metadata for valid tokens 1`] = `
--> -->
<link rel="manifest" href="./manifest.json" /> <link rel="manifest" href="./manifest.json" />
<link rel="preconnect" href="https://www.google-analytics.com/" />
<link rel="preload" href="./fonts/Inter-roman.var.woff2" as="font" type="font/woff2" crossorigin /> <link rel="preload" href="./fonts/Inter-roman.var.woff2" as="font" type="font/woff2" crossorigin />
<style> <style>
...@@ -156,7 +154,7 @@ exports[`should inject metadata for valid tokens 2`] = ` ...@@ -156,7 +154,7 @@ exports[`should inject metadata for valid tokens 2`] = `
<meta <meta
http-equiv="Content-Security-Policy" http-equiv="Content-Security-Policy"
content="script-src 'self' https://www.google-analytics.com https://www.googletagmanager.com 'unsafe-inline'" content="script-src 'self' 'unsafe-inline'"
/> />
...@@ -172,8 +170,6 @@ exports[`should inject metadata for valid tokens 2`] = ` ...@@ -172,8 +170,6 @@ exports[`should inject metadata for valid tokens 2`] = `
--> -->
<link rel="manifest" href="./manifest.json" /> <link rel="manifest" href="./manifest.json" />
<link rel="preconnect" href="https://www.google-analytics.com/" />
<link rel="preload" href="./fonts/Inter-roman.var.woff2" as="font" type="font/woff2" crossorigin /> <link rel="preload" href="./fonts/Inter-roman.var.woff2" as="font" type="font/woff2" crossorigin />
<style> <style>
...@@ -290,7 +286,7 @@ exports[`should inject metadata for valid tokens 3`] = ` ...@@ -290,7 +286,7 @@ exports[`should inject metadata for valid tokens 3`] = `
<meta <meta
http-equiv="Content-Security-Policy" http-equiv="Content-Security-Policy"
content="script-src 'self' https://www.google-analytics.com https://www.googletagmanager.com 'unsafe-inline'" content="script-src 'self' 'unsafe-inline'"
/> />
...@@ -306,8 +302,6 @@ exports[`should inject metadata for valid tokens 3`] = ` ...@@ -306,8 +302,6 @@ exports[`should inject metadata for valid tokens 3`] = `
--> -->
<link rel="manifest" href="./manifest.json" /> <link rel="manifest" href="./manifest.json" />
<link rel="preconnect" href="https://www.google-analytics.com/" />
<link rel="preload" href="./fonts/Inter-roman.var.woff2" as="font" type="font/woff2" crossorigin /> <link rel="preload" href="./fonts/Inter-roman.var.woff2" as="font" type="font/woff2" crossorigin />
<style> <style>
...@@ -424,7 +418,7 @@ exports[`should inject metadata for valid tokens 4`] = ` ...@@ -424,7 +418,7 @@ exports[`should inject metadata for valid tokens 4`] = `
<meta <meta
http-equiv="Content-Security-Policy" http-equiv="Content-Security-Policy"
content="script-src 'self' https://www.google-analytics.com https://www.googletagmanager.com 'unsafe-inline'" content="script-src 'self' 'unsafe-inline'"
/> />
...@@ -440,8 +434,6 @@ exports[`should inject metadata for valid tokens 4`] = ` ...@@ -440,8 +434,6 @@ exports[`should inject metadata for valid tokens 4`] = `
--> -->
<link rel="manifest" href="./manifest.json" /> <link rel="manifest" href="./manifest.json" />
<link rel="preconnect" href="https://www.google-analytics.com/" />
<link rel="preload" href="./fonts/Inter-roman.var.woff2" as="font" type="font/woff2" crossorigin /> <link rel="preload" href="./fonts/Inter-roman.var.woff2" as="font" type="font/woff2" crossorigin />
<style> <style>
...@@ -558,7 +550,7 @@ exports[`should inject metadata for valid tokens 5`] = ` ...@@ -558,7 +550,7 @@ exports[`should inject metadata for valid tokens 5`] = `
<meta <meta
http-equiv="Content-Security-Policy" http-equiv="Content-Security-Policy"
content="script-src 'self' https://www.google-analytics.com https://www.googletagmanager.com 'unsafe-inline'" content="script-src 'self' 'unsafe-inline'"
/> />
...@@ -574,8 +566,6 @@ exports[`should inject metadata for valid tokens 5`] = ` ...@@ -574,8 +566,6 @@ exports[`should inject metadata for valid tokens 5`] = `
--> -->
<link rel="manifest" href="./manifest.json" /> <link rel="manifest" href="./manifest.json" />
<link rel="preconnect" href="https://www.google-analytics.com/" />
<link rel="preload" href="./fonts/Inter-roman.var.woff2" as="font" type="font/woff2" crossorigin /> <link rel="preload" href="./fonts/Inter-roman.var.woff2" as="font" type="font/woff2" crossorigin />
<style> <style>
......
...@@ -44,7 +44,7 @@ const invalidCollections = [ ...@@ -44,7 +44,7 @@ const invalidCollections = [
] ]
test.each(invalidCollections)( test.each(invalidCollections)(
'should not inject metadata for invalid urls', 'should not inject metadata for invalid collection urls',
async (url) => { async (url) => {
const body = await fetch(new Request(url)).then((res) => res.text()) const body = await fetch(new Request(url)).then((res) => res.text())
expect(body).not.toContain('og:title') expect(body).not.toContain('og:title')
......
...@@ -8,17 +8,14 @@ type MetaTagInjectorInput = { ...@@ -8,17 +8,14 @@ type MetaTagInjectorInput = {
* Listener class for Cloudflare's HTMLRewriter {@link https://developers.cloudflare.com/workers/runtime-apis/html-rewriter} * Listener class for Cloudflare's HTMLRewriter {@link https://developers.cloudflare.com/workers/runtime-apis/html-rewriter}
* to inject meta tags into the <head> of an HTML document. * to inject meta tags into the <head> of an HTML document.
*/ */
export class MetaTagInjector { export class MetaTagInjector implements HTMLRewriterElementContentHandlers {
constructor(private input: MetaTagInjectorInput) {} constructor(private input: MetaTagInjectorInput) {}
append(element, property: string, content: string) { append(element: Element, property: string, content: string) {
element.append(`<meta property="${property}" content="${content}"/>`, { html: true }) element.append(`<meta property="${property}" content="${content}"/>`, { html: true })
} }
/** element(element: Element) {
* Event handler for ElementHandler {@link https://developers.cloudflare.com/workers/runtime-apis/html-rewriter/#element-handlers}
*/
element(element) {
//Open Graph Tags //Open Graph Tags
this.append(element, 'og:title', this.input.title) this.append(element, 'og:title', this.input.title)
if (this.input.image) { if (this.input.image) {
......
...@@ -6,5 +6,6 @@ ...@@ -6,5 +6,6 @@
"'^.+\\.(ts|tsx)?$'": "ts-jest", "'^.+\\.(ts|tsx)?$'": "ts-jest",
"^.+\\.(js|jsx)$": "babel-jest" "^.+\\.(js|jsx)$": "babel-jest"
}, },
"testTimeout": 50000 "testTimeout": 360000,
"cacheDirectory": "../node_modules/.cache/cloud-jest"
} }
...@@ -48,7 +48,7 @@ const invalidAssets = [ ...@@ -48,7 +48,7 @@ const invalidAssets = [
'http://127.0.0.1:3000/nfts/asset/0xed5af388653567af2f388e6224dc7c4b3241c544//2550', 'http://127.0.0.1:3000/nfts/asset/0xed5af388653567af2f388e6224dc7c4b3241c544//2550',
] ]
test.each(invalidAssets)('should not inject metadata for invalid calls', async (url) => { test.each(invalidAssets)('should not inject metadata for invalid asset calls', async (url) => {
const body = await fetch(new Request(url)).then((res) => res.text()) const body = await fetch(new Request(url)).then((res) => res.text())
expect(body).not.toContain('og:title') expect(body).not.toContain('og:title')
expect(body).not.toContain('og:image') expect(body).not.toContain('og:image')
......
...@@ -3,17 +3,17 @@ ...@@ -3,17 +3,17 @@
"esModuleInterop": true, "esModuleInterop": true,
"incremental": true, "incremental": true,
"lib": ["DOM", "DOM.Iterable", "ESNext"], "lib": ["DOM", "DOM.Iterable", "ESNext"],
"moduleResolution": "node",
"module": "esnext",
"noEmit": true, "noEmit": true,
"strict": true, "strict": true,
"target": "ES6", "target": "ESNext",
"tsBuildInfoFile": "../node_modules/.cache/tsbuildinfo/functions", // avoid clobbering the build tsbuildinfo "tsBuildInfoFile": "../node_modules/.cache/tsbuildinfo/functions", // avoid clobbering the build tsbuildinfo
"types": ["jest", "node"], "types": ["jest", "node", "@cloudflare/workers-types"],
"jsx": "react", "jsx": "react",
"moduleResolution": "NodeNext", "skipLibCheck": true,
"baseUrl": "functions"
}, },
"exclude": ["node_modules"], "exclude": ["../node_modules", "../src"],
"include": ["**/*.ts"], "include": ["**/*.ts"],
"watchOptions": {
"excludeDirectories": ["node_modules"]
}
} }
\ No newline at end of file
...@@ -26,8 +26,9 @@ ...@@ -26,8 +26,9 @@
"serve": "serve build -l 3000", "serve": "serve build -l 3000",
"lint": "yarn eslint --ignore-path .gitignore --cache --cache-location node_modules/.cache/eslint/ .", "lint": "yarn eslint --ignore-path .gitignore --cache --cache-location node_modules/.cache/eslint/ .",
"typecheck": "tsc", "typecheck": "tsc",
"typecheck:cloud": "tsc -p functions/tsconfig.json",
"test": "craco test", "test": "craco test",
"test:cloud": "NODE_OPTIONS=--experimental-vm-modules yarn jest functions --watch --config=functions/jest.config.json", "test:cloud": "NODE_OPTIONS=--experimental-vm-modules yarn jest functions --config=functions/jest.config.json",
"cypress:open": "cypress open --browser chrome --e2e", "cypress:open": "cypress open --browser chrome --e2e",
"cypress:run": "cypress run --browser chrome --e2e", "cypress:run": "cypress run --browser chrome --e2e",
"deduplicate": "yarn-deduplicate --strategy=highest" "deduplicate": "yarn-deduplicate --strategy=highest"
...@@ -70,7 +71,7 @@ ...@@ -70,7 +71,7 @@
"devDependencies": { "devDependencies": {
"@babel/plugin-proposal-private-property-in-object": "^7.21.11", "@babel/plugin-proposal-private-property-in-object": "^7.21.11",
"@babel/preset-env": "^7.22.7", "@babel/preset-env": "^7.22.7",
"@cloudflare/workers-types": "^4.20230518.0", "@cloudflare/workers-types": "^4.20230710.1",
"@craco/craco": "^7.1.0", "@craco/craco": "^7.1.0",
"@ethersproject/experimental": "^5.4.0", "@ethersproject/experimental": "^5.4.0",
"@lingui/cli": "^3.9.0", "@lingui/cli": "^3.9.0",
......
...@@ -1392,10 +1392,10 @@ ...@@ -1392,10 +1392,10 @@
dependencies: dependencies:
mime "^3.0.0" mime "^3.0.0"
"@cloudflare/workers-types@^4.20230518.0": "@cloudflare/workers-types@^4.20230710.1":
version "4.20230518.0" version "4.20230710.1"
resolved "https://registry.yarnpkg.com/@cloudflare/workers-types/-/workers-types-4.20230518.0.tgz#de1b0f71d68e2eac1b546542968ea2b837cb967e" resolved "https://registry.yarnpkg.com/@cloudflare/workers-types/-/workers-types-4.20230710.1.tgz#a527537d9ee856c9b476b33b0909e516235f2cb5"
integrity sha512-A0w1V+5SUawGaaPRlhFhSC/SCDT9oQG8TMoWOKFLA4qbqagELqEAFD4KySBIkeVOvCBLT1DZSYBMCxbXddl0kw== integrity sha512-VqEY/ZqyHKBn6ivdePSWebpqojwbCXVEuwLkMYHs0UoOAqcGylkVcabdZYdQJKeNxXcOUZ9UBId/x9UsPUm2XQ==
"@coinbase/wallet-sdk@^3.6.4": "@coinbase/wallet-sdk@^3.6.4":
version "3.6.4" version "3.6.4"
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment