Skip to content

Commit

Permalink
BO44
Browse files Browse the repository at this point in the history
  • Loading branch information
camillobucciarelli committed Aug 9, 2024
1 parent 2df2e33 commit d5c15d4
Show file tree
Hide file tree
Showing 21 changed files with 489 additions and 98 deletions.
22 changes: 14 additions & 8 deletions astro.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,21 @@ import tailwind from "@astrojs/tailwind";
import nodejs from "@astrojs/node";
import astroI18next from "astro-i18next";
import icon from "astro-icon";
import { defaultLanguage, supportedLanguages } from "~/constants/i18n.js";

// https://astro.build/config
export default defineConfig({
site: "https://devfest.gdgpescara.it",
integrations: [icon({
include: {
mdi: ["*"], // (Default) Loads entire Material Design Icon set
},
}),react(), tailwind(), astroI18next()],
integrations: [
icon({
include: {
mdi: ["*"], // (Default) Loads entire Material Design Icon set
},
}),
react(),
tailwind(),
astroI18next(),
],
output: "hybrid",
adapter: nodejs({
mode: "standalone",
Expand All @@ -21,10 +27,10 @@ export default defineConfig({
domains: ["via.placeholder.com"],
},
i18n: {
defaultLocale: "en",
locales: ["en", "it"],
defaultLocale: defaultLanguage,
locales: supportedLanguages,
fallback: {
it: "en",
it: defaultLanguage,
},
routingStrategy: "prefix-other-locales",
},
Expand Down
5 changes: 5 additions & 0 deletions src/constants/i18n.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export const defaultLanguage = "en" as const;

export const supportedLanguages = ["it", "en"] as const;

export type SupportedLanguages = (typeof supportedLanguages)[number];
46 changes: 29 additions & 17 deletions src/data/firestore/common/create.spec.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { test, describe, expect } from "vitest";
import { createDocument } from "./create";
import { getDocumentById } from "./get-by-id";
import { testConverter, type TestDoc, type TestModel } from "./test-model";
import { describe, expect, test } from "vitest";
import createDocument from "./create";
import { defaultLanguage } from "~/constants/i18n";
import {testConverter, type TestDoc, type TestModel} from "./test-model";
import type { FirestoreDataConverter } from "firebase-admin/firestore";

const testCollection = "create-test";
Expand All @@ -11,29 +11,18 @@ describe("Create a new document", () => {
const modelToSave: TestModel = {
lastUpdate: new Date("2024-01-01"),
name: "Test Document",
description: "Test description",
};
const result = await createDocument(
testCollection,
testConverter,
modelToSave,
defaultLanguage,
);
expect(result).toMatchObject({
status: "success",
data: expect.any(String),
});

const getResult = await getDocumentById(
testCollection,
testConverter,
result.data as string,
);
expect(getResult).toMatchObject({
status: "success",
data: expect.objectContaining({
...modelToSave,
id: result.data,
}),
});
});

test("Should return an error if id is present", async () => {
Expand All @@ -46,6 +35,7 @@ describe("Create a new document", () => {
testCollection,
testConverter,
modelToSave,
defaultLanguage,
);
expect(result).toMatchObject({
status: "error",
Expand Down Expand Up @@ -73,6 +63,7 @@ describe("Create a new document", () => {
testCollection,
fakeConverter,
modelToSave,
defaultLanguage,
);
expect(result).toMatchObject({
status: "error",
Expand All @@ -93,6 +84,7 @@ describe("Create a new document", () => {
testCollection,
testConverter,
modelToSave,
defaultLanguage,
);
expect(result).toMatchObject({
status: "error",
Expand All @@ -102,4 +94,24 @@ describe("Create a new document", () => {
},
});
});

test("Should return an error if passed language is not default one", async () => {
const modelToSave: TestModel = {
lastUpdate: new Date("2024-01-01"),
name: "Test Document",
};
const result = await createDocument(
testCollection,
testConverter,
modelToSave,
"it",
);
expect(result).toMatchObject({
status: "error",
data: {
code: `${testCollection}/create-error:default-language-is-required`,
message: "Default language is required",
},
});
});
});
24 changes: 18 additions & 6 deletions src/data/firestore/common/create.ts
Original file line number Diff line number Diff line change
@@ -1,26 +1,36 @@
import type {
DocumentData,
FirestoreDataConverter,
} from "firebase-admin/firestore";
import { firestoreInstance } from "~/firebase/server";
import type { BaseModel } from "~/models/base-model";
import type { ServerResponse } from "~/models/server-response/server-response.type";
import { defaultLanguage, type SupportedLanguages } from "~/constants/i18n";
import type {DocumentData, FirestoreDataConverter} from "firebase-admin/firestore";

export const createDocument = async <
const createDocument = async <
M extends BaseModel,
D extends DocumentData,
C extends string,
>(
collection: C,
converter: FirestoreDataConverter<M, D>,
model: M,
currentLanguage: SupportedLanguages,
): Promise<
ServerResponse<
string,
`${C}/create-error` | `${C}/create-error:id-is-present`
| `${C}/create-error`
| `${C}/create-error:id-is-present`
| `${C}/create-error:default-language-is-required`
>
> => {
try {
if (currentLanguage !== defaultLanguage) {
return {
status: "error",
data: {
code: `${collection}/create-error:default-language-is-required`,
message: "Default language is required",
},
};
}
if (model.id) {
return {
status: "error",
Expand Down Expand Up @@ -49,3 +59,5 @@ export const createDocument = async <
};
}
};

export default createDocument;
35 changes: 3 additions & 32 deletions src/data/firestore/common/delete.spec.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { describe, expect, test } from "vitest";
import { deleteDocument } from "./delete";
import { createDocument } from "./create";
import { getDocumentById } from "./get-by-id";
import { testConverter, type TestModel } from "./test-model";
import createDocument from "./create";
import { defaultLanguage } from "~/constants/i18n";

const testCollection = "delete-test";

Expand All @@ -17,22 +17,9 @@ describe("deleteDocument", () => {
testCollection,
testConverter,
modelToSave,
defaultLanguage,
);

const get = await getDocumentById(
testCollection,
testConverter,
result.data as string,
);

expect(get).toMatchObject({
status: "success",
data: expect.objectContaining({
...modelToSave,
id: result.data,
}),
});

const deleteResult = await deleteDocument(
testCollection,
result.data as string,
Expand All @@ -42,22 +29,6 @@ describe("deleteDocument", () => {
status: "success",
data: null,
});

const getAfterDelete = await getDocumentById(
testCollection,
testConverter,
result.data as string,
);

expect(getAfterDelete).toMatchObject({
status: "error",
data: {
code: `${testCollection}/get-by-id-error:not-found`,
message: `Document with id ${
result.data as string
} not found in collection delete-test`,
},
});
});

test("should return an error if id is missing", async () => {
Expand Down
5 changes: 4 additions & 1 deletion src/data/firestore/common/get-by-id.spec.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import { describe, expect, test } from "vitest";
import { createDocument } from "./create";
import { getDocumentById } from "./get-by-id";
import { testConverter, type TestDoc, type TestModel } from "./test-model";
import type { FirestoreDataConverter } from "firebase-admin/firestore";
import createDocument from "./create";
import { defaultLanguage } from "~/constants/i18n";

const testCollection = "get-by-id-test";

Expand All @@ -17,6 +18,7 @@ describe("Get by id", () => {
testCollection,
testConverter,
modelToSave,
defaultLanguage,
);

const get = await getDocumentById(
Expand Down Expand Up @@ -84,6 +86,7 @@ describe("Get by id", () => {
testCollection,
testConverter,
modelToSave,
defaultLanguage,
);

const fakeConverter: FirestoreDataConverter<TestModel, TestDoc> = {
Expand Down
34 changes: 20 additions & 14 deletions src/data/firestore/common/test-model.ts
Original file line number Diff line number Diff line change
@@ -1,31 +1,37 @@
import type {LocalizedFirestoreDocument} from "~/data/firestore/docs/model-document-mapper";
import {type FirestoreDataConverter, type QueryDocumentSnapshot, Timestamp} from "firebase-admin/firestore";
import {
QueryDocumentSnapshot,
Timestamp,
type FirestoreDataConverter,
} from "firebase-admin/firestore";
import type { FirestoreDocument } from "~/data/model-document-mapper";
localizedFieldFromFirestore,
localizedFieldToFirestore
} from "~/data/firestore/docs/converters/localization-converter.ts";
import omit from "~/data/firestore/docs/utils.ts";

export type TestModel = {
id?: string;
name: string;
description?: string;
lastUpdate: Date;
};

export type TestDoc = FirestoreDocument<TestModel>;
type TestDocLocalizedFields = "description";

export type TestDoc = LocalizedFirestoreDocument<TestModel, TestDocLocalizedFields>

export const testConverter: FirestoreDataConverter<TestModel, TestDoc> = {
toFirestore: (company: TestModel): TestDoc => {
return {
...company,
lastUpdate: Timestamp.fromDate(company.lastUpdate),
toFirestore: (model: TestModel): TestDoc => {
const rest = omit(model, ["id", "description"]);
const doc: TestDoc = {
...rest,
lastUpdate: Timestamp.fromDate(model.lastUpdate),
};
return localizedFieldToFirestore(model, "en", ["description"], doc);
},
fromFirestore: (snapshot: QueryDocumentSnapshot): TestModel => {
const data = snapshot.data();
const model = localizedFieldFromFirestore<TestModel, TestDocLocalizedFields>(snapshot, "en", ["description"]);
return {
id: snapshot.id,
...data,
...model,
lastUpdate: data.lastUpdate.toDate(),
} as TestModel;
};
},
};
};
5 changes: 4 additions & 1 deletion src/data/firestore/common/update.spec.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import { test, describe, expect } from "vitest";
import { updateDocument } from "./update";
import { getDocumentById } from "./get-by-id";
import { createDocument } from "./create";
import { testConverter, type TestDoc, type TestModel } from "./test-model";
import type { FirestoreDataConverter } from "firebase-admin/firestore";
import createDocument from "./create";
import { defaultLanguage } from "~/constants/i18n";

const testCollection = "update-test";

Expand All @@ -18,6 +19,7 @@ describe("Update a new document", () => {
testCollection,
testConverter,
modelToSave,
defaultLanguage,
);

const modelToUpdate = {
Expand Down Expand Up @@ -88,6 +90,7 @@ describe("Update a new document", () => {
testCollection,
testConverter,
modelToSave,
defaultLanguage,
);

const modelToUpdate = {
Expand Down
Loading

0 comments on commit d5c15d4

Please sign in to comment.