Skip to content

Commit

Permalink
updating to v14
Browse files Browse the repository at this point in the history
  • Loading branch information
charliewilco committed Feb 19, 2024
1 parent 462f811 commit 5688745
Show file tree
Hide file tree
Showing 10 changed files with 83 additions and 50 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/e2e.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,6 @@ jobs:
- name: Install Playwright
run: pnpm deps
- name: Build Project for Testing
run: yarn build
run: pnpm build
- name: Run Playwright
run: pnpm test
1 change: 0 additions & 1 deletion next-env.d.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
/// <reference types="next" />
/// <reference types="next/image-types/global" />
/// <reference types="next/navigation-types/compat/navigation" />

// NOTE: This file should not be edited
// see https://nextjs.org/docs/basic-features/typescript for more information.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
"deps": "playwright install --with-deps"
},
"dependencies": {
"mongodb": "^6.3.0",
"mongoose": "^8.1.3",
"next": "^14.1.0",
"react": "^18.2.0",
Expand Down
3 changes: 3 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion src/app/[id]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ export default async function DetailsPage({
<div className="card">
<div className="DetailGrid">
<div>
<p>{person.age}</p>
<p id="age">{person.age}</p>
<span className="label">Age</span>
</div>
<div>
Expand Down
15 changes: 12 additions & 3 deletions src/app/actions.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
"use server";

import { revalidateTag, revalidatePath, unstable_cache } from "next/cache";
import { DBAdapter, type PersonDocument, type PersonType } from "../db/adapter";

type ContactFormValues = {
Expand Down Expand Up @@ -54,14 +55,14 @@ export async function createContact(
}
await DBAdapter.instance.connect();
let person = await DBAdapter.instance.models.person.create(data);

revalidateTag("people");
return {
ok: true,
data: {
name: person?.name,
city: person?.city,
age: person?.age,
id: person?._id,
id: person?.id,
},
};
}
Expand Down Expand Up @@ -91,6 +92,9 @@ export async function updateContact(
runValidators: true,
});

revalidatePath(`/${id}`);
revalidateTag("people");

return {
ok: true,
data: {
Expand All @@ -110,6 +114,7 @@ export async function deleteContact(
let removed = await DBAdapter.instance.models.person.deleteOne({ _id: id });

console.log(removed);
revalidateTag("people");
return {
ok: true,
data: { message: "Contact deleted" },
Expand All @@ -130,9 +135,13 @@ export async function getPeople(): Promise<PersonType[]> {
return people ?? [];
}

export const cachedPeople = unstable_cache(getPeople, [], {
tags: ["people"],
});

export async function getPerson(id: string): Promise<PersonType | null> {
await DBAdapter.instance.connect();
try {
await DBAdapter.instance.connect();
let result = await DBAdapter.instance.models.person.findById(id);
if (result !== null) {
return DBAdapter.toPerson(result);
Expand Down
4 changes: 2 additions & 2 deletions src/app/page.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import type { Metadata } from "next";
import { ContactCard } from "../components/card";
import { getPeople } from "./actions";
import { cachedPeople } from "./actions";

export const metadata: Metadata = {
title: "MongoDB Next.js Demo",
};

export default async function IndexPage() {
let people = await getPeople();
let people = await cachedPeople();

let content: JSX.Element | JSX.Element[];

Expand Down
9 changes: 6 additions & 3 deletions src/db/adapter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ export type PersonType = {
name: string;
age: number;
city: string;
}
};

interface ConntectionStatus {
isConnected?: number;
Expand All @@ -49,11 +49,14 @@ export class DBAdapter {
connection: ConntectionStatus = {};

models: Models = {
person: mongoose.models.Person || mongoose.model<PersonDocument>("Person", PersonSchema),
person:
mongoose.models.Person ||
mongoose.model<PersonDocument>("Person", PersonSchema),
};

constructor(
private connectionURL = process.env.DB_ADDRESS || "mongodb://127.0.0.1:27017/next-js-demo"
private connectionURL = process.env.DB_ADDRESS ||
"mongodb://127.0.0.1:27017/next-js-demo"
) {}

async connect() {
Expand Down
24 changes: 24 additions & 0 deletions src/db/client.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { MongoClient, Collection, Document } from "mongodb";

let client: MongoClient;
let db: Collection;

export interface PersonDocument extends Document {
name: string;
age: number;
city: string;
}

async function connect() {
client = new MongoClient(
process.env.DB_ADDRESS ?? "mongodb://127.0.0.1:27017"
);
await client.connect();
db = client.db("next-js-demo").collection("persons");
}

async function disconnect() {
await client.close();
}

export { connect, disconnect, db as persons };
72 changes: 33 additions & 39 deletions test/crud.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,62 +2,56 @@ import { expect, test } from "@playwright/test";
import { DBAdapter } from "../src/db/adapter";

test.beforeAll(async () => {
await DBAdapter.instance.connect();
await DBAdapter.instance.drop();
await DBAdapter.instance.connect();
await DBAdapter.instance.drop();
});

test.afterAll(async () => {
await DBAdapter.instance.disconnect();
await DBAdapter.instance.disconnect();
});

test("should find link", async ({ page }) => {
await page.goto("/");
await page.goto("/");

await page.click("text=About");
await expect(page).toHaveURL("/about");
await expect(page.locator("h1")).toContainText("About");
await page.click("text=About");
await expect(page).toHaveURL("/about");
await expect(page.locator("h1")).toContainText("About");
});

test("should create a new item", async ({ page }) => {
await page.goto("/");
await page.click("text=New");
await expect(page).toHaveURL("/new");

await page.type("input[name='name']", "Charlie");

await page.fill("input[name='age']", "");
await page.type("input[name='age']", "37");
await page.fill("input[name='city']", "");
await page.type("input[name='city']", "Tacoma, WA");

await page.click("button[type='submit']");

await expect(page.locator(".card")).toContainText("Charlie");
await expect(page.locator(".city")).toContainText("Tacoma, WA");
await expect(page.locator(".city")).not.toContainText("Seattle");
await page.goto("/");
await page.getByRole("link", { name: "New" }).click();
await page.locator('input[name="name"]').click();
await page.locator('input[name="name"]').fill("Charlie");
await page.locator('input[name="name"]').press("Tab");
await page.locator('input[name="city"]').fill("Tacoma");
await page.locator('input[name="city"]').press("Tab");
await page.getByRole("spinbutton").fill("33");
await page.getByRole("button", { name: "Submit" }).click();
expect(page.locator("#age")).toContainText("33");
});

test("can update item", async ({ page }) => {
await page.goto("/");
await page.click("text=Edit");
await page.fill("input[name='name']", "");
await page.type("input[name='name']", "Rutherford");
await page.click("button[type='submit']");
await page.goto("/");

await expect(page.locator("h5")).toContainText("Rutherford");
await expect(page.locator(".city")).toContainText("Tacoma, WA");
await page.getByRole("button", { name: "Edit" }).click();
await page.locator('input[name="name"]').click();
await page.locator('input[name="name"]').press("Meta+a");
await page.locator('input[name="name"]').fill("Rutherford");
await page.locator('input[name="name"]').press("Tab");
await page.locator('input[name="city"]').fill("Portland");
await page.getByRole("button", { name: "Submit" }).click();

await page.goto("/");
await expect(page.locator("h5")).toContainText("Rutherford");
expect(page.locator("h1")).toContainText("Rutherford");
});

test("can remove item", async ({ page }) => {
await page.goto("/");
await page.click("text=Details");
test.skip("can remove item", async ({ page }) => {
await page.goto("/");
await page.click("text=Details");

await expect(page.locator("h1")).toContainText("Rutherford");
await expect(page.locator("h1")).toContainText("Rutherford");

await page.click("text=Delete");
await expect(page).toHaveURL("/");
await expect(page.locator(".empty")).toContainText("No people found");
await page.click("text=Delete");
await expect(page).toHaveURL("/");
await expect(page.locator(".empty")).toContainText("No people found");
});

0 comments on commit 5688745

Please sign in to comment.