Skip to content

Commit

Permalink
Add actions test workflow (#34)
Browse files Browse the repository at this point in the history
* Add actions test workflow

* Set up test

* Add env

* Tweaks

* Tweak quota

* Bump eslint
  • Loading branch information
tmcw committed Feb 3, 2024
1 parent 6c02951 commit 6fbe905
Show file tree
Hide file tree
Showing 20 changed files with 378 additions and 253 deletions.
127 changes: 127 additions & 0 deletions .eslintrc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
const config = require("@blitzjs/next/eslint");

module.exports = {
...config,
env: {
browser: true,
es2021: true,
},
ignorePatterns: ["workers", "vendor", "docs"],
settings: {
react: {
version: "detect",
},
},
// extends: [
// "blitz",
// "eslint:recommended",
// "plugin:react/recommended",
// "plugin:@typescript-eslint/recommended",
// ],
parser: "@typescript-eslint/parser",
parserOptions: {
ecmaFeatures: {
jsx: true,
},
ecmaVersion: 12,
sourceType: "module",
},
plugins: ["react", "react-hooks", "@typescript-eslint", "unused-imports"],
rules: {
"react/react-in-jsx-scope": 0,
"react/display-name": 0,
"jsx-a11y/no-onchange": 0,
"jsx-a11y/no-autofocus": 0,
"no-console": ["error"],
"no-warning-comments": ["error", { terms: ["fixme"] }],
"no-restricted-imports": [
"error",
{ paths: ["lodash", "purify-ts", "proj4"] },
],
"no-throw-literal": "error",
"prefer-const": 1,
"require-await": 1,
"react/jsx-key": 2,
"react/prop-types": 0,
"react/no-unescaped-entities": 0,
"@next/next/no-img-element": 0,
"@typescript-eslint/no-non-null-assertion": 0,
"@typescript-eslint/explicit-module-boundary-types": 0,
"@typescript-eslint/ban-types": 1,
"react/jsx-no-useless-fragment": 2,
"@typescript-eslint/no-explicit-any": 0,
"@typescript-eslint/no-empty-function": 0,
"react-hooks/rules-of-hooks": "error",
"@typescript-eslint/no-unused-vars": [
"error",
{ argsIgnorePattern: "^_", ignoreRestSiblings: true },
],
"react-hooks/exhaustive-deps": [
"warn",
{
additionalHooks: "(useRecoilCallback|useRecoilTransaction_UNSTABLE)",
},
],
},
overrides: [
{
files: ["*.ts", "*.tsx"], // Your TypeScript files extension
parserOptions: {
project: ["./tsconfig.json"], // Specify it only for TypeScript files
},
extends: [
"plugin:@typescript-eslint/recommended-requiring-type-checking",
],
rules: {
"prefer-const": 1,
"unused-imports/no-unused-imports": "error",
"@typescript-eslint/no-explicit-any": 0,
"@typescript-eslint/no-base-to-string": 0,
"@typescript-eslint/no-floating-promises": 1,
"@typescript-eslint/switch-exhaustiveness-check": 2,
"@typescript-eslint/no-misused-promises": 0,
"@typescript-eslint/no-unnecessary-type-assertion": 1,
"@typescript-eslint/no-unsafe-return": 1,
// This will trip an error in linting/CI
// because Routes will not be generated.
"@typescript-eslint/no-unsafe-call": 1,
"@typescript-eslint/no-unsafe-assignment": 0,
"@typescript-eslint/no-unsafe-argument": 1,
"@typescript-eslint/no-unsafe-member-access": 0,
"@typescript-eslint/unbound-method": 0,
},
},
{
files: ["./*.config.js", ".eslintrc.js"],
env: {
commonjs: true,
},
},
{
files: ["./vendor/*/*"],
rules: {
complexity: 0,
"no-warning-comments": 0,
},
},
{
files: ["./vendor/mapshaper/**/*", "./vendor/mproj.js"],
rules: {
"@typescript-eslint/no-loss-of-precision": 0,
"no-console": 0,
"@typescript-eslint/no-unused-vars": 0,
"@typescript-eslint/no-var-requires": 0,
"@typescript-eslint/no-this-alias": 0,
"no-extra-boolean-cast": 0,
"no-useless-escape": 0,
"no-empty": 0,
"no-warning-comments": 0,
"no-undef": 0,
"no-constant-condition": 0,
"no-control-regex": 0,
"no-prototype-builtins": 0,
"react-hooks/rules-of-hooks": 0,
},
},
],
};
79 changes: 79 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
name: Node CI

on: [push]

jobs:
test:
runs-on: ubuntu-latest
env:
NODE_ENV: test
DATABASE_URL: postgresql://postgres:postgres@localhost:5432/placemark_test
NEXT_PUBLIC_FILE_WARN_MB: 5
NEXT_PUBLIC_FILE_LIMIT_MB: 5
PUSHER_SERVER_INTERNAL_ADDRESS: xxx
NEXT_PUBLIC_STRIPE_PRICE_ID_ENTERPRISE: xx
PUSHER_SERVER_INTERNAL_PORT: xxx
NEXT_PUBLIC_POSTHOG_API_HOST: xxx
NEXT_PUBLIC_POSTHOG_API_TOKEN: xxx
NEXT_PUBLIC_MAPBOX_TOKEN: pk.eyJ1IjoidG1jdyIsImEiOiJja2twd25qdWowMXBuMnVxdDZodXJzaDZoIn0.UL4e2OtC7xrGr9hohU1odg
BLOG_RSS_URL: xxx
WFC_QUOTA: 10
WFC_QUOTA_ENTERPRISE: 100
TEAM_EMAIL: foo@bar.com
DOMAIN: test.local
CAMPAIGNMONITOR_KEY: xxx
CYPRESS_INSTALL_BINARY: 0
GITHUB_CLIENT_ID: xx
GITHUB_CLIENT_SECRET: xx
strategy:
matrix:
node-version: [20.x]
services:
postgres:
image: postgres:16
env:
POSTGRES_PASSWORD: postgres
options: >-
--health-cmd pg_isready
--health-interval 10s
--health-timeout 5s
--health-retries 5
ports:
- 5432:5432
steps:
- name: Check out repo
uses: actions/checkout@v4
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node-version }}
- name: Get yarn cache directory path
id: yarn-cache-dir-path
run: echo "::set-output name=dir::$(yarn cache dir)"
- uses: actions/cache@v4
id: yarn-cache # use this to check for `cache-hit` (`steps.yarn-cache.outputs.cache-hit != 'true'`)
with:
path: ${{ steps.yarn-cache-dir-path.outputs.dir }}
key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}
restore-keys: |
${{ runner.os }}-yarn-
- uses: actions/cache@v4
id: cache-next
with:
path: ${{ github.workspace }}/.next/cache
# Generate a new cache whenever packages or source files change.
key: ${{ runner.os }}-nextjs-${{ hashFiles('**/yarn.lock') }}-${{ hashFiles('**.[jt]sx?') }}
# If source files changed but packages didn't, rebuild from a prior cache.
restore-keys: |
${{ runner.os }}-nextjs-${{ hashFiles('**/yarn.lock') }}-
- name: Install packages
run: |
yarn install --frozen-lockfile
- name: Migrate DB & generate prisma client
run: yarn blitz prisma migrate dev
- name: Lint
run: |
yarn lint
- name: Run tests with coverage
run: |
yarn test
1 change: 1 addition & 0 deletions app/auth/mutations/signup.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ vi.mock("integrations/stripe", () => {
env: {
STRIPE_PRICE_ID: "0000",
},
stripeEnabled: false,
createStripeCheckoutSession: vi.fn().mockReturnValue({
id: "xyz",
}),
Expand Down
1 change: 1 addition & 0 deletions app/auth/mutations/signup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@ export default resolver.pipe(

return;
} catch (e) {
// eslint-disable-next-line
console.error(e);
}
}
Expand Down
6 changes: 3 additions & 3 deletions app/blitz-server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,19 +37,19 @@ export const { gSSP, gSP, api } = setupBlitzServer({
if (e instanceof ZodError) {
res.statusCode = 400;
// https://github.com/blitz-js/blitz/issues/4295
// @ts-ignore-next
// @ts-expect-error This is a bug in Blitz defs
res.send({ error: "Bad request", issues: e.issues });

Check warning on line 41 in app/blitz-server.ts

View workflow job for this annotation

GitHub Actions / test (20.x)

Unsafe call of an `any` typed value

Check warning on line 41 in app/blitz-server.ts

View workflow job for this annotation

GitHub Actions / test (20.x)

Unsafe call of an `any` typed value
res.end();
return;
} else if (e instanceof Prisma.PrismaClientKnownRequestError) {
res.statusCode = 404;
// @ts-ignore-next
// @ts-expect-error This is a bug in Blitz defs
res.send({ error: "Not found" });

Check warning on line 47 in app/blitz-server.ts

View workflow job for this annotation

GitHub Actions / test (20.x)

Unsafe call of an `any` typed value

Check warning on line 47 in app/blitz-server.ts

View workflow job for this annotation

GitHub Actions / test (20.x)

Unsafe call of an `any` typed value
res.end();
return;
}
res.statusCode = 500;
// @ts-ignore-next
// @ts-expect-error This is a bug in Blitz defs
res.send({ error: "Internal error" });

Check warning on line 53 in app/blitz-server.ts

View workflow job for this annotation

GitHub Actions / test (20.x)

Unsafe call of an `any` typed value

Check warning on line 53 in app/blitz-server.ts

View workflow job for this annotation

GitHub Actions / test (20.x)

Unsafe call of an `any` typed value
res.end();
return;
Expand Down
6 changes: 6 additions & 0 deletions app/lib/env_server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -88,25 +88,31 @@ export const env = envsafe({
});

if (env.WORKOS_API_KEY === "off") {
// eslint-disable-next-line
console.log("Disabling WorkOS integration");
}

if (env.LOGTAIL_TOKEN === "off") {
// eslint-disable-next-line
console.log("Disabling Logtail integration");
}

if (env.STRIPE_SECRET_KEY === "off") {
// eslint-disable-next-line
console.log("Disabling Stripe integration");
}

if (env.CAMPAIGNMONITOR_KEY === "off") {
// eslint-disable-next-line
console.log("Disabling Campaignmonitor integration");
}

if (env.CLOUDFLARE_API_TOKEN === "off") {
// eslint-disable-next-line
console.log("Disabling Cloudflare integration");
}

if (env.POSTMARK_SERVER_API_TOKEN === "off") {
// eslint-disable-next-line
console.log("Disabling Postmark integration");
}
3 changes: 2 additions & 1 deletion app/lib/utils_server.server.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { AuthenticatedCtx } from "blitz";
import { getRandomMockCtxAndUser } from "test/shared";
import { enforceWfcQuota, parseSymbolization } from "./utils_server";
import { env } from "app/lib/env_client";
import { env as env_server } from "app/lib/env_server";
import db from "db";
import createWrappedFeatureCollection from "app/wrappedFeatureCollections/mutations/createWrappedFeatureCollection";
import { SYMBOLIZATION_NONE } from "types";
Expand All @@ -17,7 +18,7 @@ describe("enforceWfcQuota", () => {
const { ctx } = await getRandomMockCtxAndUser();
await expect(enforceWfcQuota(ctx as AuthenticatedCtx)).resolves.toBeFalsy();

for (let i = 0; i < 50; i++) {
for (let i = 0; i < env_server.WFC_QUOTA; i++) {
await expect(
createWrappedFeatureCollection({ name: "Foo" }, ctx)
).resolves.toBeTruthy();
Expand Down
1 change: 1 addition & 0 deletions app/memberships/mutations/acceptInvitation.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ beforeAll(() => {

vi.mock("integrations/stripe", () => {
return {
stripeEnabled: false,
default: {
customers: {
create: vi.fn(() => ({
Expand Down
1 change: 1 addition & 0 deletions app/memberships/mutations/deleteMembership.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ vi.mock("integrations/stripe", () => {
STRIPE_PRICE_ID: "0000",
},
},
stripeEnabled: false,
updateQuantityForOrganization() {
return Promise.resolve(true);
},
Expand Down
1 change: 1 addition & 0 deletions app/memberships/mutations/pauseMembership.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ beforeAll(() => {

vi.mock("integrations/stripe", () => {
return {
stripeEnabled: false,
default: {
customers: {
create: vi.fn(() => ({
Expand Down
1 change: 1 addition & 0 deletions app/organizations/mutations/changeOrganizationName.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ vi.mock("integrations/stripe", () => {
update: vi.fn().mockReturnValue(Promise.resolve(true)),
},
},
stripeEnabled: false,
};
});

Expand Down
5 changes: 3 additions & 2 deletions app/organizations/mutations/createOrganization.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,9 @@ vi.mock("integrations/stripe", () => {
env: {
STRIPE_PRICE_ID: "0000",
},
stripeEnabled: false,
createStripeCheckoutSession() {
return Promise.resolve({ id: "0001" });
return Promise.resolve({ id: "0021" });
},
};
});
Expand All @@ -39,6 +40,6 @@ describe("createOrganization", () => {
},
ctx
)
).toEqual("0001");
).toEqual("");
});
});
5 changes: 3 additions & 2 deletions app/organizations/mutations/deleteOrganization.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,9 @@ vi.mock("integrations/stripe", () => {
STRIPE_PRICE_ID: "0000",
},
},
stripeEnabled: true,
createStripeCheckoutSession() {
return Promise.resolve({ id: "0001" });
return Promise.resolve({ id: "0201" });
},
};
});
Expand Down Expand Up @@ -64,7 +65,7 @@ describe("deleteOrganization", () => {
},
ctx
)
).toEqual("0001");
).toEqual("0201");
expect(await db.membership.count({ where: { userId: user.id } })).toEqual(
2
);
Expand Down
1 change: 1 addition & 0 deletions app/organizations/queries/getOrganization.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ vi.mock("integrations/stripe", () => {
updateQuantityForOrganization(_id: any) {
return Promise.resolve(true);
},
stripeEnabled: false,
};
});

Expand Down
3 changes: 0 additions & 3 deletions integrations/posthog_client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,6 @@ import { env } from "app/lib/env_client";
export const posthog = env.NEXT_PUBLIC_POSTHOG_API_TOKEN === "off" ? null : ph;

export const usePostHog = () => {
if (env.NEXT_PUBLIC_POSTHOG_API_TOKEN === "off") {
return null;
}
const router = useRouter();

useEffect(() => {
Expand Down
1 change: 1 addition & 0 deletions integrations/stripe.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { notifyTeam } from "./notify_team";
export * from "stripe";

if (env.STRIPE_SECRET_KEY === "off") {
// eslint-disable-next-line
console.log(`STRIPE_SECRET_KEY not found: disabling Stripe integration`);
}

Expand Down
Loading

0 comments on commit 6fbe905

Please sign in to comment.