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
This commit is contained in:
Brendan Wong 2023-07-25 12:12:13 -07:00 committed by GitHub
parent b230cb62f4
commit 22112c763c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 68 additions and 55 deletions

@ -169,6 +169,41 @@ jobs:
name: Cypress tests
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:
if: ${{ github.ref_name == 'main' || github.ref_name == 'releases/staging' }}
runs-on: ubuntu-latest

1
.gitignore vendored

@ -19,6 +19,7 @@ schema.graphql
# testing
/coverage
/cache
/functions/coverage
# builds
/build

@ -22,7 +22,7 @@ exports[`should inject metadata for valid collections 1`] = `
<meta
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`] = `
-->
<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 />
<style>
@ -156,7 +154,7 @@ exports[`should inject metadata for valid collections 2`] = `
<meta
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`] = `
-->
<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 />
<style>
@ -290,7 +286,7 @@ exports[`should inject metadata for valid collections 3`] = `
<meta
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`] = `
-->
<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 />
<style>

@ -22,7 +22,7 @@ exports[`should inject metadata for valid assets 1`] = `
<meta
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`] = `
-->
<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 />
<style>
@ -156,7 +154,7 @@ exports[`should inject metadata for valid assets 2`] = `
<meta
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`] = `
-->
<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 />
<style>
@ -290,7 +286,7 @@ exports[`should inject metadata for valid assets 3`] = `
<meta
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`] = `
-->
<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 />
<style>

@ -22,7 +22,7 @@ exports[`should inject metadata for valid tokens 1`] = `
<meta
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`] = `
-->
<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 />
<style>
@ -156,7 +154,7 @@ exports[`should inject metadata for valid tokens 2`] = `
<meta
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`] = `
-->
<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 />
<style>
@ -290,7 +286,7 @@ exports[`should inject metadata for valid tokens 3`] = `
<meta
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`] = `
-->
<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 />
<style>
@ -424,7 +418,7 @@ exports[`should inject metadata for valid tokens 4`] = `
<meta
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`] = `
-->
<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 />
<style>
@ -558,7 +550,7 @@ exports[`should inject metadata for valid tokens 5`] = `
<meta
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`] = `
-->
<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 />
<style>

@ -44,7 +44,7 @@ const invalidCollections = [
]
test.each(invalidCollections)(
'should not inject metadata for invalid urls',
'should not inject metadata for invalid collection urls',
async (url) => {
const body = await fetch(new Request(url)).then((res) => res.text())
expect(body).not.toContain('og:title')

@ -8,17 +8,14 @@ type MetaTagInjectorInput = {
* 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.
*/
export class MetaTagInjector {
export class MetaTagInjector implements HTMLRewriterElementContentHandlers {
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 })
}
/**
* Event handler for ElementHandler {@link https://developers.cloudflare.com/workers/runtime-apis/html-rewriter/#element-handlers}
*/
element(element) {
element(element: Element) {
//Open Graph Tags
this.append(element, 'og:title', this.input.title)
if (this.input.image) {

@ -6,5 +6,6 @@
"'^.+\\.(ts|tsx)?$'": "ts-jest",
"^.+\\.(js|jsx)$": "babel-jest"
},
"testTimeout": 50000
"testTimeout": 360000,
"cacheDirectory": "../node_modules/.cache/cloud-jest"
}

@ -48,7 +48,7 @@ const invalidAssets = [
'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())
expect(body).not.toContain('og:title')
expect(body).not.toContain('og:image')

@ -3,17 +3,17 @@
"esModuleInterop": true,
"incremental": true,
"lib": ["DOM", "DOM.Iterable", "ESNext"],
"moduleResolution": "node",
"module": "esnext",
"noEmit": true,
"strict": true,
"target": "ES6",
"target": "ESNext",
"tsBuildInfoFile": "../node_modules/.cache/tsbuildinfo/functions", // avoid clobbering the build tsbuildinfo
"types": ["jest", "node"],
"types": ["jest", "node", "@cloudflare/workers-types"],
"jsx": "react",
"moduleResolution": "NodeNext",
"skipLibCheck": true,
"baseUrl": "functions"
},
"exclude": ["node_modules"],
"exclude": ["../node_modules", "../src"],
"include": ["**/*.ts"],
"watchOptions": {
"excludeDirectories": ["node_modules"]
}
}

@ -26,8 +26,9 @@
"serve": "serve build -l 3000",
"lint": "yarn eslint --ignore-path .gitignore --cache --cache-location node_modules/.cache/eslint/ .",
"typecheck": "tsc",
"typecheck:cloud": "tsc -p functions/tsconfig.json",
"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:run": "cypress run --browser chrome --e2e",
"deduplicate": "yarn-deduplicate --strategy=highest"
@ -70,7 +71,7 @@
"devDependencies": {
"@babel/plugin-proposal-private-property-in-object": "^7.21.11",
"@babel/preset-env": "^7.22.7",
"@cloudflare/workers-types": "^4.20230518.0",
"@cloudflare/workers-types": "^4.20230710.1",
"@craco/craco": "^7.1.0",
"@ethersproject/experimental": "^5.4.0",
"@lingui/cli": "^3.9.0",

@ -1392,10 +1392,10 @@
dependencies:
mime "^3.0.0"
"@cloudflare/workers-types@^4.20230518.0":
version "4.20230518.0"
resolved "https://registry.yarnpkg.com/@cloudflare/workers-types/-/workers-types-4.20230518.0.tgz#de1b0f71d68e2eac1b546542968ea2b837cb967e"
integrity sha512-A0w1V+5SUawGaaPRlhFhSC/SCDT9oQG8TMoWOKFLA4qbqagELqEAFD4KySBIkeVOvCBLT1DZSYBMCxbXddl0kw==
"@cloudflare/workers-types@^4.20230710.1":
version "4.20230710.1"
resolved "https://registry.yarnpkg.com/@cloudflare/workers-types/-/workers-types-4.20230710.1.tgz#a527537d9ee856c9b476b33b0909e516235f2cb5"
integrity sha512-VqEY/ZqyHKBn6ivdePSWebpqojwbCXVEuwLkMYHs0UoOAqcGylkVcabdZYdQJKeNxXcOUZ9UBId/x9UsPUm2XQ==
"@coinbase/wallet-sdk@^3.6.4":
version "3.6.4"