Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 9 additions & 19 deletions .env.example
Original file line number Diff line number Diff line change
@@ -1,23 +1,13 @@
# Since the ".env" file is gitignored, you can use the ".env.example" file to
# build a new ".env" file when you clone the repo. Keep this file up-to-date
# when you add new variables to `.env`.
DATABASE_URL=""

# This file will be committed to version control, so make sure not to have any
# secrets in it. If you are cloning this repo, create a copy of this file named
# ".env" and populate it with your secrets.
NEXT_PUBLIC_SITE_URL=""

# When adding additional environment variables, the schema in "/src/env.mjs"
# should be updated accordingly.

# Prisma
# https://www.prisma.io/docs/reference/database-reference/connection-urls#env
DATABASE_URL="file:./db.sqlite"

# Next Auth
# You can generate a new secret on the command line with:
# openssl rand -base64 32
# https://next-auth.js.org/configuration/options#secret
# NEXTAUTH_SECRET=""
NEXTAUTH_URL="http://localhost:3000"
AUTH0_CLIENT_ID=""
AUTH0_CLIENT_SECRET=""
AUTH0_ISSUER=""

CYPRESS_TEST_USER_EMAIL=""
CYPRESS_TEST_USER_PASSWORD=""

TEST_USER_EMAIL=""
TEST_USER_PASSWORD=""
7 changes: 7 additions & 0 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@ jobs:
steps:
- name: Checkout
uses: actions/checkout@v3
# Write the cypress.env.json file
- name: Write the cypress.env.json file 📝
run: |
echo '${{ secrets.CYPRESS_ENV_CI }}' > cypress.env.json && cat cypress.env.json
# Install NPM dependencies, cache them correctly
# and run all Cypress tests
- name: Cypress run
Expand All @@ -25,3 +29,6 @@ jobs:
AUTH0_CLIENT_ID: ${{ secrets.AUTH0_CLIENT_ID }}
AUTH0_CLIENT_SECRET: ${{ secrets.AUTH0_CLIENT_SECRET }}
AUTH0_ISSUER: ${{ secrets.AUTH0_ISSUER }}
TEST_USER_EMAIL: ${{ secrets.TEST_USER_EMAIL }}
TEST_USER_PASSWORD: ${{ secrets.TEST_USER_PASSWORD }}
CYPRESS_ENV_CI: ${{ secrets.CYPRESS_ENV_CI }}
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -44,3 +44,5 @@ yarn-error.log*

cypress/videos
cypress/screenshots
cypress/downloads
cypress.env.json
3 changes: 0 additions & 3 deletions cypress.config.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
import { defineConfig } from "cypress";

export default defineConfig({
env: {
NEXT_PUBLIC_SITE_URL: "http://localhost:3000",
},
viewportHeight: 1000,
e2e: {
setupNodeEvents(on, config) {
Expand Down
1 change: 1 addition & 0 deletions cypress/e2e/study/controls.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import gamesBySquares from "../../utils/gamesBySquares";

describe("Check that controls move around", () => {
beforeEach(() => {
cy.login();
cy.visit(`${Cypress.env("NEXT_PUBLIC_SITE_URL")}/study`);
cy.playGame(gamesBySquares.shortExample);
});
Expand Down
1 change: 1 addition & 0 deletions cypress/e2e/study/fen.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import gamesBySquares from "../../utils/gamesBySquares";

describe("Check that controls move around", () => {
beforeEach(() => {
cy.login();
cy.visit(`${Cypress.env("NEXT_PUBLIC_SITE_URL")}/study`);
});

Expand Down
1 change: 1 addition & 0 deletions cypress/e2e/study/moves.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import gamesBySquares from "../../utils/gamesBySquares";

describe("Check that PgnViewer component works as expected", () => {
beforeEach(() => {
cy.login();
cy.visit(`${Cypress.env("NEXT_PUBLIC_SITE_URL")}/study`);
});

Expand Down
1 change: 1 addition & 0 deletions cypress/e2e/study/pgnTools/copyPgn.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import gamesBySquares from "../../../utils/gamesBySquares";

describe("Check functioning of PGN copying", () => {
beforeEach(() => {
cy.login();
cy.visit(`${Cypress.env("NEXT_PUBLIC_SITE_URL")}/study`);
});

Expand Down
3 changes: 2 additions & 1 deletion cypress/e2e/study/pgnTools/downloadPgn.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import gamesBySquares from "../../../utils/gamesBySquares";

describe("Check functioning of PGN download", () => {
beforeEach(() => {
cy.login();
cy.visit(`${Cypress.env("NEXT_PUBLIC_SITE_URL")}/study`);
});

Expand All @@ -14,7 +15,7 @@ describe("Check functioning of PGN download", () => {
cy.data("download-pgn").should("be.enabled");
});

it.only("Should copy PGN to clipboard", () => {
it("Should copy PGN to clipboard", () => {
cy.playGame(gamesBySquares.shortExample);
cy.data("pgn-tools-menu").click();
cy.data("download-pgn").click();
Expand Down
1 change: 1 addition & 0 deletions cypress/e2e/study/pgnViewer.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import gamesBySquares from "../../utils/gamesBySquares";

describe("Check that PgnViewer shows correct moves", () => {
beforeEach(() => {
cy.login();
cy.visit(`${Cypress.env("NEXT_PUBLIC_SITE_URL")}/study`);
});

Expand Down
1 change: 1 addition & 0 deletions cypress/e2e/study/study.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import gamesBySquares from "../../utils/gamesBySquares";

describe("Check basic moves in study", () => {
beforeEach(() => {
cy.login();
cy.visit(`${Cypress.env("NEXT_PUBLIC_SITE_URL")}/study`);
});

Expand Down
28 changes: 28 additions & 0 deletions cypress/support/commands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ declare global {
testBoardStore(): Chainable<void>;
testStudyStore(): Chainable<void>;
assertValueCopiedToClipboard(value: string): void;
login(): void;
}
}
}
Expand Down Expand Up @@ -60,3 +61,30 @@ Cypress.Commands.add("assertValueCopiedToClipboard", (value) => {
cy.wrap(win.navigator.clipboard.readText()).should("eq", value);
});
});

Cypress.Commands.add("login", () => {
cy.session(
"login",
() => {
console.log(
"logging in!",
Cypress.env("TEST_USER_EMAIL"),
Cypress.env("TEST_USER_PASSWORD")
);
cy.visit(`${Cypress.env("NEXT_PUBLIC_SITE_URL")}`);
cy.data("sign-in-out").click();
cy.get("button").contains("Sign in with Auth0").click();
cy.origin("https://opening-expert.us.auth0.com", () => {
cy.get("#username").type(Cypress.env("TEST_USER_EMAIL"));
cy.get("#password")
.type(Cypress.env("TEST_USER_PASSWORD"))
.type("{enter}");
});
},
{
validate: () => {
cy.getCookie("next-auth.session-token").should("exist");
},
}
);
});
6 changes: 6 additions & 0 deletions src/components/Study/Study.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,14 @@ import { HStack } from "@chakra-ui/react";
import PgnViewer from "~/components/PgnViewer/PgnViewer";
import Board from "~/components/Board/Board";
import PositionInfo from "~/components/PositionInfo/PositionInfo";
import useStudyStore from "~/state/study";
import { useEffect } from "react";

const Study = () => {
const { loadPGN } = useStudyStore();
useEffect(() => {
//loadPGN("1. e4 h5 (1... a5) 2. f4");
}, []);
return (
<>
<HStack alignItems={"flex-start"}>
Expand Down
13 changes: 0 additions & 13 deletions src/env.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -9,17 +9,6 @@ export const env = createEnv({
server: {
DATABASE_URL: z.string(),
NODE_ENV: z.enum(["development", "test", "production"]),
NEXTAUTH_SECRET:
process.env.NODE_ENV === "production"
? z.string().min(1)
: z.string().min(1).optional(),
NEXTAUTH_URL: z.preprocess(
// This makes Vercel deployments not fail if you don't set NEXTAUTH_URL
// Since NextAuth.js automatically uses the VERCEL_URL if present.
(str) => process.env.VERCEL_URL ?? str,
// VERCEL_URL doesn't include `https` so it cant be validated as a URL
process.env.VERCEL ? z.string().min(1) : z.string().url(),
),
AUTH0_CLIENT_ID: z.string().min(1),
AUTH0_CLIENT_SECRET: z.string().min(1),
AUTH0_ISSUER: z.string().min(1),
Expand All @@ -42,8 +31,6 @@ export const env = createEnv({
runtimeEnv: {
DATABASE_URL: process.env.DATABASE_URL,
NODE_ENV: process.env.NODE_ENV,
NEXTAUTH_SECRET: process.env.NEXTAUTH_SECRET,
NEXTAUTH_URL: process.env.NEXTAUTH_URL,
NEXT_PUBLIC_SITE_URL: process.env.NEXT_PUBLIC_SITE_URL,
AUTH0_CLIENT_ID: process.env.AUTH0_CLIENT_ID,
AUTH0_CLIENT_SECRET: process.env.AUTH0_CLIENT_SECRET,
Expand Down
2 changes: 1 addition & 1 deletion src/pages/index.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { type NextPage } from "next";
import { signIn, signOut, useSession } from "next-auth/react";
import Head from "next/head";
import { api } from "~/api";
import Link from "next/link";
import { Heading } from "@chakra-ui/react";

Expand All @@ -25,6 +24,7 @@ const Home: NextPage = () => {
</p>
<button
onClick={sessionData ? () => void signOut() : () => void signIn()}
data-cy={"sign-in-out"}
>
{sessionData ? "Sign out" : "Sign in / Sign up"}
</button>
Expand Down
3 changes: 3 additions & 0 deletions src/pages/study.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
import Study from "~/components/Study/Study";
import generateAuthGSSP from "~/utils/generateAuthGSSP";

export const getServerSideProps = generateAuthGSSP("/study");

const StudyPage = () => {
return <Study />;
Expand Down
28 changes: 27 additions & 1 deletion src/state/study.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,13 @@ interface MoveData {
dests: Dests;
}

type MoveDataByIndex = Map<Index, MoveData>;

interface StudyState {
id: string;
parent: string | null;
chess: Chess;
moveDataByIndex: Map<number, MoveData>;
moveDataByIndex: MoveDataByIndex;
branches: Map<Index, StudyState[]>;
currentMoveIndex: Index;
setCurrentMoveIndex: (index: Index) => void;
Expand All @@ -26,6 +28,7 @@ interface StudyState {
moveLength: () => number;
currentFen: () => FEN;
move: (orig: Key, dest: Key) => void;
loadPGN: (pgn: PGN) => void;
}

const toDests = (fen: FEN): Dests => {
Expand All @@ -45,7 +48,9 @@ const toDests = (fen: FEN): Dests => {
};

const promotionCalcChess = new Chess();

const isPromotion = (fen: FEN, orig: Key, dest: Key): boolean => {
console.log("fen", fen);
promotionCalcChess.load(fen);
return promotionCalcChess
.move({ from: orig, to: dest, promotion: "q" })
Expand Down Expand Up @@ -116,6 +121,27 @@ const useStudyStore = create<StudyState>()(
todo(null);
}
},
loadPGN: (pgn) => {
const chess = new Chess();
chess.loadPgn(pgn);
const moves = pgn.split(" ");
const newMoveDataByIndex: MoveDataByIndex = new Map().set(0, {
fen: initialFen,
dests: toDests(initialFen),
});
chess.history({ verbose: true }).map((move, i) => {
console.log("setting", i + 1, move.after);
newMoveDataByIndex.set(i + 1, {
fen: move.after,
dests: toDests(move.after),
});
});
set(() => ({
chess,
moveDataByIndex: newMoveDataByIndex,
currentMoveIndex: 0,
}));
},
};
})
);
Expand Down
23 changes: 23 additions & 0 deletions src/utils/generateAuthGSSP.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { GetServerSideProps } from "next";
import { getServerAuthSession } from "~/server/auth";

type GenerateAuthGSSP = (callbackUrl: string) => GetServerSideProps;

const generateAuthGSSP: GenerateAuthGSSP = (callbackUrl) => async (ctx) => {
const session = await getServerAuthSession(ctx);
if (session) {
return {
props: {
session,
},
};
}
return {
redirect: {
destination: `/api/auth/signin?callbackUrl=${callbackUrl}`,
permanent: false,
},
};
};

export default generateAuthGSSP;