Skip to content

Commit

Permalink
Green: Switch purchase time to timestamp (todos)
Browse files Browse the repository at this point in the history
- update firebase sample data
- test that playwright tests didn't get 10x as slow, and that that's really just my laptop battery
  • Loading branch information
bmitchinson committed Mar 13, 2024
1 parent 2b58c6e commit 06266d9
Show file tree
Hide file tree
Showing 11 changed files with 128 additions and 72 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
"ios": "npm run build && npm run sync && npm run xcode",
"xcode": "cap open ios",
"firebase": "firebase emulators:start --import ./firestore-emulator-data",
"firebase-export": "firebase emulators:export ./firestore-emulator-data",
"report": "playwright show-report",
"test-all-browser": "playwright test --workers=1",
"test-gui": "playwright test --ui --workers=1",
Expand Down
40 changes: 26 additions & 14 deletions src/components/entry/EntryForm.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -4,31 +4,37 @@
import CategorySelect from "./CategorySelect.svelte";
import { Database } from "../../lib/Database";
import { Timestamp } from "firebase/firestore";
import { purchaseBeingEdited } from "../../lib/Stores";
import {
purchaseAskingToConfirmDelete,
purchaseBeingEdited,
} from "../../lib/Stores";
import type { Purchase } from "../../lib/DatabaseTypes";
import {
datetimeToTimestamp,
initialDatetimeString,
timestampToDatetimeString,
} from "../../lib/utils/DateUtils";
App.addListener("appStateChange", ({ isActive }) => {
isActive && document.getElementById("amount")?.focus();
});
const today = new Date();
const month = String(today.getMonth() + 1).padStart(2, "0");
const day = String(today.getDate()).padStart(2, "0");
const selectedDate = `${today.getFullYear()}-${month}-${day}`;
console.log("Initial Datetime String from app: ", initialDatetimeString);
const { form, handleChange, handleSubmit, handleReset } = createForm({
initialValues: {
amount: "",
category: "",
date: selectedDate,
purchaseDatetime: initialDatetimeString,
description: "",
},
onSubmit: (formData) => {
const entryTime = Timestamp.fromDate(new Date());
const purchase: Purchase = {
...formData,
purchaseDatetime: datetimeToTimestamp(formData.purchaseDatetime),
amount: parseFloat(formData.amount) || 0,
entryTime,
entryDatetime: entryTime,
};
if ($purchaseBeingEdited) {
Database.get()
Expand All @@ -52,13 +58,19 @@
form.set({
amount: purchase.amount.toString(),
category: purchase.category,
date: purchase.date,
purchaseDatetime: timestampToDatetimeString(purchase.purchaseDatetime),
description: purchase.description,
});
} else {
handleReset();
}
});
purchaseAskingToConfirmDelete.subscribe((purchaseRef) => {
if (purchaseRef == undefined) {
handleReset();
}
});
</script>

<div class="entry-form">
Expand Down Expand Up @@ -95,14 +107,14 @@
</div>

<div class="row-item space-between">
<label for="date">Date</label>
<label for="datetime">Date/Time</label>
<input
id="date"
name="date"
type="date"
data-testid="date-input"
id="datetime"
name="datetime"
type="datetime-local"
data-testid="datetime-input"
on:change={handleChange}
bind:value={$form.date}
bind:value={$form.purchaseDatetime}
/>
</div>

Expand Down
6 changes: 0 additions & 6 deletions src/components/purchases/PastPurchase.svelte
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
<script lang="ts">
import { get } from "svelte/store";
import { Database } from "../../lib/Database";
import type {
Purchase,
Expand Down Expand Up @@ -50,11 +49,6 @@
Database.get().deletePurchase(purchase.ref);
} else {
purchaseAskingToConfirmDelete.set(purchase.ref);
console.log(
purchase.ref.id +
" set conf to " +
get(purchaseAskingToConfirmDelete)?.id
);
}
}}>{deleteConfirmationActive ? "confirm" : "delete"}</button
></th
Expand Down
1 change: 1 addition & 0 deletions src/components/purchases/PastPurchasesList.svelte
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
<script lang="ts">
import { get } from "svelte/store";
import { Database } from "../../lib/Database";
import { purchaseBeingEdited } from "../../lib/Stores";
import PastPurchase from "./PastPurchase.svelte";
Expand Down
5 changes: 1 addition & 4 deletions src/lib/Database.ts
Original file line number Diff line number Diff line change
Expand Up @@ -136,13 +136,10 @@ export class Database {
}

private initializePurchasesSubscription() {
// todo-postshadcn: date needs to become purchaseTime
// want to sort by date, not entry. Date isn't specific enough to sort.
// todo-postshadcn: get all within timespan from UI, instead of limiting to 15
// todo-postshadcn -> sort in most recent first
const q = query(
collection(this.db, "purchases"),
orderBy("entryTime"),
orderBy("purchaseDatetime", "desc"),
limit(15)
);

Expand Down
7 changes: 2 additions & 5 deletions src/lib/DatabaseTypes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,9 @@ export type FirebaseDocumentRef = DocumentReference;
export interface Purchase {
amount: number;
category: string;
// TODO:
// refactor: purchaseDateTime
date: string;
purchaseDatetime: Timestamp;
description: string;
// refactor: entryDateTime
entryTime: Timestamp;
entryDatetime: Timestamp;
}

export type WithFirebaseDocumentRef<T> = T & { ref: FirebaseDocumentRef };
4 changes: 4 additions & 0 deletions src/lib/Logging.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
export const logInfo = (msg: String) => {
console.log("🧿 // " + msg);
};

export const logDebug = (msg: String) => {
console.log("⚙️ // " + msg);
};
15 changes: 15 additions & 0 deletions src/lib/utils/DateUtils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { format, parse } from "date-fns";
import { Timestamp } from "firebase/firestore";

export const datetimeStringFormat = "yyyy-MM-dd'T'HH:mm";

export const dateToDatetimeString = (date: Date) =>
format(date, datetimeStringFormat);

export const initialDatetimeString = dateToDatetimeString(new Date());

export const datetimeToTimestamp = (datetime: string) =>
Timestamp.fromDate(parse(datetime, datetimeStringFormat, new Date()));

export const timestampToDatetimeString = (timestamp: Timestamp) =>
format(timestamp.toDate(), datetimeStringFormat);
24 changes: 15 additions & 9 deletions tests/CommonTestOperations.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,21 @@
import { expect, type Page } from "@playwright/test";
import { format } from "date-fns";
import { format, parse } from "date-fns";

export const mockedClockDatetimeString = "2023-05-12T01:30";

export const mockedClockDate = parse(
mockedClockDatetimeString,
"yyyy-MM-dd'T'HH:mm",
new Date()
);

export const fillPurchaseFormWithValidData = async (page: Page) => {
await page.getByLabel("Amount").fill("10.77");
await page.getByLabel("Description").fill("cool thing");
await page.getByLabel("Description").fill("cool trip");
await page.locator("#category-input").press("Delete");
await page.locator("#category-input").fill("Gas");
await page.locator(".sv-item").first().click();
await page.getByLabel("Date").fill("2023-09-21");
await page.getByLabel("Date/Time").fill(mockedClockDatetimeString);
};

export const clickEditAtPurchaseIndex = async (page: Page, index: number) => {
Expand All @@ -26,12 +35,12 @@ export const clickDeletePurchaseAtIndex = async (page: Page, index: number) => {
};

export const expectFormToBeEmpty = async (page: Page) => {
const today = format(new Date(), "yyyy-MM-dd");

await expect(await amountOnForm(page)).toBe("");
await expect(await descriptionOnForm(page)).toBe("");
await expect(await categoryOnForm(page)).toBe("");
await expect(await dateOnForm(page)).toBe(today);
await expect(page.getByTestId("datetime-input")).toHaveValue(
new RegExp(mockedClockDatetimeString)
);
};

export const purchasesOnPage = async (page: Page) => {
Expand All @@ -53,9 +62,6 @@ export const categoryOnForm = async (page: Page) => {
}
};

export const dateOnForm = async (page: Page) =>
await page.getByTestId("date-input").inputValue();

export const expectTheseAtPurchaseIndex = async (
page: Page,
values: string[],
Expand Down
21 changes: 11 additions & 10 deletions tests/DatabaseTestUtil.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,29 +3,30 @@
import { Timestamp } from "firebase/firestore";
import type { Purchase } from "../src/lib/DatabaseTypes";
import { Database } from "../src/lib/Database";
import { add } from "date-fns";
import { add, sub } from "date-fns";
import { mockedClockDate } from "./CommonTestOperations";

const fakePurchases: Purchase[] = [
{
amount: 123.45,
category: "Gas",
date: "2021-01-01",
description: "Item One",
entryTime: Timestamp.fromDate(new Date()),
purchaseDatetime: Timestamp.fromDate(sub(mockedClockDate, { minutes: 3 })),
description: "Morning Drive",
entryDatetime: Timestamp.fromDate(new Date()),
},
{
amount: 456.12,
category: "Restaurants",
date: "2021-01-02",
description: "Item Two",
entryTime: Timestamp.fromDate(add(new Date(), { seconds: 10 })),
purchaseDatetime: Timestamp.fromDate(sub(mockedClockDate, { minutes: 2 })),
description: "Lunch",
entryDatetime: Timestamp.fromDate(new Date()),
},
{
amount: 100,
category: "Date Night",
date: "2021-01-03",
description: "Item Three",
entryTime: Timestamp.fromDate(add(new Date(), { seconds: 20 })),
purchaseDatetime: Timestamp.fromDate(sub(mockedClockDate, { minutes: 1 })),
description: "Centro",
entryDatetime: Timestamp.fromDate(new Date()),
},
];

Expand Down
Loading

0 comments on commit 06266d9

Please sign in to comment.