mirror of
https://github.com/hay-kot/homebox.git
synced 2025-05-22 21:32:28 +00:00
feat: currency selection support (#72)
* initial UI for currency selection * add task to purge invitation tokens * group API contracts * fix type import * use auth middleware * add currency setting support (UI) * use group settings for format currency * fix casing
This commit is contained in:
parent
1cc38d6a5c
commit
461be2afca
40 changed files with 930 additions and 343 deletions
|
@ -1,6 +1,5 @@
|
|||
import { describe, test, expect } from "vitest";
|
||||
import { factories } from "./factories";
|
||||
import { sharedUserClient } from "./test-utils";
|
||||
|
||||
describe("[GET] /api/v1/status", () => {
|
||||
test("server should respond", async () => {
|
||||
|
@ -32,43 +31,4 @@ describe("first time user workflow (register, login, join group)", () => {
|
|||
expect(response.status).toBe(204);
|
||||
}
|
||||
});
|
||||
|
||||
test("user should be able to join create join token and have user signup", async () => {
|
||||
// Setup User 1 Token
|
||||
|
||||
const client = await sharedUserClient();
|
||||
const { data: user1 } = await client.user.self();
|
||||
|
||||
const { response, data } = await client.group.createInvitation({
|
||||
expiresAt: new Date(Date.now() + 1000 * 60 * 60 * 24 * 7),
|
||||
uses: 1,
|
||||
});
|
||||
|
||||
expect(response.status).toBe(201);
|
||||
expect(data.token).toBeTruthy();
|
||||
|
||||
// Create User 2 with token
|
||||
|
||||
const duplicateUser = factories.user();
|
||||
duplicateUser.token = data.token;
|
||||
|
||||
const { response: registerResp } = await api.register(duplicateUser);
|
||||
expect(registerResp.status).toBe(204);
|
||||
|
||||
const { response: loginResp, data: loginData } = await api.login(duplicateUser.email, duplicateUser.password);
|
||||
expect(loginResp.status).toBe(200);
|
||||
|
||||
// Get Self and Assert
|
||||
|
||||
const client2 = factories.client.user(loginData.token);
|
||||
|
||||
const { data: user2 } = await client2.user.self();
|
||||
|
||||
user2.item.groupName = user1.item.groupName;
|
||||
|
||||
// Cleanup User 2
|
||||
|
||||
const { response: deleteResp } = await client2.user.delete();
|
||||
expect(deleteResp.status).toBe(204);
|
||||
});
|
||||
});
|
||||
|
|
66
frontend/lib/api/__test__/user/group.test.ts
Normal file
66
frontend/lib/api/__test__/user/group.test.ts
Normal file
|
@ -0,0 +1,66 @@
|
|||
import { faker } from "@faker-js/faker";
|
||||
import { describe, test, expect } from "vitest";
|
||||
import { factories } from "../factories";
|
||||
import { sharedUserClient } from "../test-utils";
|
||||
|
||||
describe("first time user workflow (register, login, join group)", () => {
|
||||
test("user should be able to update group", async () => {
|
||||
const { client } = await factories.client.singleUse();
|
||||
|
||||
const name = faker.name.firstName();
|
||||
|
||||
const { response, data: group } = await client.group.update({
|
||||
name,
|
||||
currency: "eur",
|
||||
});
|
||||
|
||||
expect(response.status).toBe(200);
|
||||
expect(group.name).toBe(name);
|
||||
});
|
||||
|
||||
test("user should be able to get own group", async () => {
|
||||
const { client } = await factories.client.singleUse();
|
||||
|
||||
const { response, data: group } = await client.group.get();
|
||||
|
||||
expect(response.status).toBe(200);
|
||||
expect(group.name).toBeTruthy();
|
||||
expect(group.currency).toBe("USD");
|
||||
});
|
||||
|
||||
test("user should be able to join create join token and have user signup", async () => {
|
||||
const api = factories.client.public();
|
||||
|
||||
// Setup User 1 Token
|
||||
const client = await sharedUserClient();
|
||||
const { data: user1 } = await client.user.self();
|
||||
|
||||
const { response, data } = await client.group.createInvitation({
|
||||
expiresAt: new Date(Date.now() + 1000 * 60 * 60 * 24 * 7),
|
||||
uses: 1,
|
||||
});
|
||||
|
||||
expect(response.status).toBe(201);
|
||||
expect(data.token).toBeTruthy();
|
||||
|
||||
// Create User 2 with token
|
||||
const duplicateUser = factories.user();
|
||||
duplicateUser.token = data.token;
|
||||
|
||||
const { response: registerResp } = await api.register(duplicateUser);
|
||||
expect(registerResp.status).toBe(204);
|
||||
|
||||
const { response: loginResp, data: loginData } = await api.login(duplicateUser.email, duplicateUser.password);
|
||||
expect(loginResp.status).toBe(200);
|
||||
|
||||
// Get Self and Assert
|
||||
const client2 = factories.client.user(loginData.token);
|
||||
const { data: user2 } = await client2.user.self();
|
||||
|
||||
user2.item.groupName = user1.item.groupName;
|
||||
|
||||
// Cleanup User 2
|
||||
const { response: deleteResp } = await client2.user.delete();
|
||||
expect(deleteResp.status).toBe(204);
|
||||
});
|
||||
});
|
|
@ -1,5 +1,5 @@
|
|||
import { BaseAPI, route } from "../base";
|
||||
import { GroupInvitation, GroupInvitationCreate } from "../types/data-contracts";
|
||||
import { Group, GroupInvitation, GroupInvitationCreate, GroupUpdate } from "../types/data-contracts";
|
||||
|
||||
export class GroupApi extends BaseAPI {
|
||||
createInvitation(data: GroupInvitationCreate) {
|
||||
|
@ -8,4 +8,17 @@ export class GroupApi extends BaseAPI {
|
|||
body: data,
|
||||
});
|
||||
}
|
||||
|
||||
update(data: GroupUpdate) {
|
||||
return this.http.put<GroupUpdate, Group>({
|
||||
url: route("/groups"),
|
||||
body: data,
|
||||
});
|
||||
}
|
||||
|
||||
get() {
|
||||
return this.http.get<Group>({
|
||||
url: route("/groups"),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,6 +16,19 @@ export interface DocumentOut {
|
|||
title: string;
|
||||
}
|
||||
|
||||
export interface Group {
|
||||
createdAt: Date;
|
||||
currency: string;
|
||||
id: string;
|
||||
name: string;
|
||||
updatedAt: Date;
|
||||
}
|
||||
|
||||
export interface GroupUpdate {
|
||||
currency: string;
|
||||
name: string;
|
||||
}
|
||||
|
||||
export interface ItemAttachment {
|
||||
createdAt: Date;
|
||||
document: DocumentOut;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue