mirror of
https://github.com/netlight/my-finance-pal-backend.git
synced 2024-11-12 17:44:15 +01:00
Merge remote-tracking branch 'origin/main' into workshop-unit-test-unfinished
This commit is contained in:
commit
a6a946e4c2
15 changed files with 130 additions and 56 deletions
9
.github/workflows/cd.yaml
vendored
9
.github/workflows/cd.yaml
vendored
|
@ -12,15 +12,18 @@ jobs:
|
|||
if: ${{ github.event.workflow_run.conclusion == 'success' && github.event.workflow_run.event == 'push' }}
|
||||
|
||||
steps:
|
||||
- uses: google-github-actions/auth@v1
|
||||
- name: Authenticate with Google Cloud
|
||||
uses: google-github-actions/auth@v1
|
||||
with:
|
||||
credentials_json: '${{ secrets.GCP_SA_KEY }}'
|
||||
|
||||
- uses: google-github-actions/setup-gcloud@v1
|
||||
- name: Setup gcloud CLI
|
||||
uses: google-github-actions/setup-gcloud@v1
|
||||
with:
|
||||
project_id: ${{ secrets.GCP_PROJECT_ID }}
|
||||
|
||||
- run: |
|
||||
- name: Deploy app to Cloud Run
|
||||
run: |
|
||||
gcloud run deploy my-finance-pal \
|
||||
--image=${{ secrets.GCP_REGION }}-docker.pkg.dev/${{ secrets.GCP_PROJECT_ID }}/cloud-run-source-deploy/my-finance-pal:${{ github.sha }} \
|
||||
--allow-unauthenticated \
|
||||
|
|
27
.github/workflows/ci.yaml
vendored
27
.github/workflows/ci.yaml
vendored
|
@ -11,17 +11,22 @@ jobs:
|
|||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- uses: actions/setup-node@v3
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: '18'
|
||||
|
||||
- run: yarn install
|
||||
- name: Install dependencies
|
||||
run: yarn install
|
||||
|
||||
- run: yarn build
|
||||
- name: Build application
|
||||
run: yarn build
|
||||
|
||||
- run: yarn test
|
||||
- name: Run unit tests
|
||||
run: yarn test:unit
|
||||
|
||||
cloud_build:
|
||||
needs: build_and_test
|
||||
|
@ -29,17 +34,21 @@ jobs:
|
|||
if: ${{ github.event_name == 'push' }}
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- uses: google-github-actions/auth@v1
|
||||
- name: Authenticate with Google Cloud
|
||||
uses: google-github-actions/auth@v1
|
||||
with:
|
||||
credentials_json: '${{ secrets.GCP_SA_KEY }}'
|
||||
|
||||
- uses: google-github-actions/setup-gcloud@v1
|
||||
- name: Setup gcloud CLI
|
||||
uses: google-github-actions/setup-gcloud@v1
|
||||
with:
|
||||
project_id: ${{ secrets.GCP_PROJECT_ID }}
|
||||
|
||||
- run: |
|
||||
- name: Submit job to Cloud Build
|
||||
run: |
|
||||
gcloud builds submit \
|
||||
--region=${{ secrets.GCP_REGION }} \
|
||||
--config cloudbuild.yaml \
|
||||
|
|
9
jest.config.integration.ts
Normal file
9
jest.config.integration.ts
Normal file
|
@ -0,0 +1,9 @@
|
|||
import baseConfig from "./jest.config"
|
||||
import { type Config } from "jest";
|
||||
|
||||
const config: Config = {
|
||||
...baseConfig,
|
||||
testRegex: ".*\\.integration\\.spec\\.ts$",
|
||||
}
|
||||
|
||||
export default config;
|
24
jest.config.ts
Normal file
24
jest.config.ts
Normal file
|
@ -0,0 +1,24 @@
|
|||
import { type Config } from "jest";
|
||||
|
||||
const config: Config = {
|
||||
moduleFileExtensions: [
|
||||
"js",
|
||||
"json",
|
||||
"ts"
|
||||
],
|
||||
rootDir: ".",
|
||||
transform: {
|
||||
"^.+\\.(t|j)s$": "ts-jest"
|
||||
},
|
||||
testEnvironment: "node",
|
||||
roots: [
|
||||
"<rootDir>/src/"
|
||||
],
|
||||
moduleDirectories: [
|
||||
"node_modules",
|
||||
"src"
|
||||
],
|
||||
setupFiles: ["./src/preStart.ts"]
|
||||
}
|
||||
|
||||
export default config;
|
9
jest.config.unit.ts
Normal file
9
jest.config.unit.ts
Normal file
|
@ -0,0 +1,9 @@
|
|||
import baseConfig from "./jest.config"
|
||||
import { type Config } from "jest";
|
||||
|
||||
const config: Config = {
|
||||
...baseConfig,
|
||||
testRegex: ".*\\.unit\\.spec\\.ts$",
|
||||
}
|
||||
|
||||
export default config;
|
24
package.json
24
package.json
|
@ -13,7 +13,8 @@
|
|||
"build": "run-s clean generate-api-types compile copy-resources",
|
||||
"lint": "eslint --ext .ts src/",
|
||||
"dev": "nodemon src/server.ts",
|
||||
"test": "jest"
|
||||
"test:unit": "jest --config \"jest.config.unit.ts\"",
|
||||
"test:integration": "jest --config \"jest.config.integration.ts\""
|
||||
},
|
||||
"dependencies": {
|
||||
"@types/supertest": "^2.0.12",
|
||||
|
@ -60,26 +61,5 @@
|
|||
"ts-node": "^10.9.1",
|
||||
"tsconfig-paths": "^4.1.2",
|
||||
"typescript": "^5.0.3"
|
||||
},
|
||||
"jest": {
|
||||
"moduleFileExtensions": [
|
||||
"js",
|
||||
"json",
|
||||
"ts"
|
||||
],
|
||||
"rootDir": ".",
|
||||
"testRegex": ".*\\.spec\\.ts$",
|
||||
"transform": {
|
||||
"^.+\\.(t|j)s$": "ts-jest"
|
||||
},
|
||||
"testEnvironment": "node",
|
||||
"roots": [
|
||||
"<rootDir>/src/"
|
||||
],
|
||||
"moduleDirectories": [
|
||||
"node_modules",
|
||||
"src"
|
||||
],
|
||||
"setupFiles": ["./src/preStart.ts"]
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,13 +19,16 @@ interface Args {
|
|||
// **** Setup **** //
|
||||
|
||||
// Command line arguments
|
||||
const args = parse<Args>({
|
||||
env: {
|
||||
type: String,
|
||||
defaultValue: process.env.NODE_ENV ?? "development",
|
||||
alias: "e",
|
||||
const args = parse<Args>(
|
||||
{
|
||||
env: {
|
||||
type: String,
|
||||
defaultValue: process.env.NODE_ENV ?? "development",
|
||||
alias: "e",
|
||||
},
|
||||
},
|
||||
});
|
||||
{ partial: true }
|
||||
);
|
||||
|
||||
// Set the env file
|
||||
const dotenvConfig = dotenv.config({
|
||||
|
|
|
@ -1,20 +1,35 @@
|
|||
import { type BudgetSummary } from "../../domain/budget";
|
||||
import type BudgetSummaryRepository from "../../repository/budget/budgetSummaryRepository";
|
||||
import type BudgetUseCases from "./budgetUseCases";
|
||||
import UUID from "../../domain/uuid";
|
||||
import type BudgetRepository from "../../repository/budget/budgetRepository";
|
||||
import { type Budget, type BudgetSummary } from "../../domain/budget";
|
||||
import UUID from "../../domain/uuid";
|
||||
|
||||
export const createBudget: (
|
||||
insertBudget: BudgetSummaryRepository["insert"]
|
||||
) => BudgetUseCases["createBudget"] = (insertBudget) => async (newBudget) => {
|
||||
const budgetSummary: BudgetSummary = {
|
||||
...newBudget,
|
||||
id: new UUID(),
|
||||
spent: 0,
|
||||
expenses: [],
|
||||
type CreateBudgetUseCase = (
|
||||
insertBudgetSummary: BudgetSummaryRepository["insert"]
|
||||
) => BudgetUseCases["createBudget"];
|
||||
|
||||
export const createBudget: CreateBudgetUseCase =
|
||||
(insertBudgetSummary) => async (newBudget) => {
|
||||
// We could also create a class for our domain objects and put functionalities s.a.
|
||||
// Budget.createFrom(newBudget) and BudgetSummary.getBudget() there
|
||||
let budgetSummary: BudgetSummary = {
|
||||
...newBudget,
|
||||
id: new UUID(),
|
||||
spent: 0,
|
||||
expenses: [],
|
||||
};
|
||||
budgetSummary = await insertBudgetSummary(budgetSummary);
|
||||
const createdBudget: Budget = {
|
||||
id: budgetSummary.id,
|
||||
spent: budgetSummary.spent,
|
||||
name: budgetSummary.name,
|
||||
limit: budgetSummary.limit,
|
||||
startDate: budgetSummary.startDate,
|
||||
endDate: budgetSummary.endDate,
|
||||
};
|
||||
|
||||
return createdBudget;
|
||||
};
|
||||
return await insertBudget(budgetSummary);
|
||||
};
|
||||
|
||||
export const getBudgetSummary: (
|
||||
findBudget: BudgetSummaryRepository["find"]
|
||||
|
|
|
@ -1,16 +1,15 @@
|
|||
import { createBudget } from "./budgetService";
|
||||
import type BudgetUseCases from "./budgetUseCases";
|
||||
import { type BudgetSummary, type NewBudget } from "../../domain/budget";
|
||||
import { type Budget, type NewBudget } from "../../domain/budget";
|
||||
import Limit from "../../domain/limit";
|
||||
|
||||
describe("budgetService", () => {
|
||||
it("calls the create function with the correct object", async () => {
|
||||
// GIVEN
|
||||
const newBudget: NewBudget = { name: "My Budget", limit: new Limit(250) };
|
||||
const expectedBudgetSummary: Omit<BudgetSummary, "id"> = {
|
||||
const expectedBudget: Omit<Budget, "id"> = {
|
||||
...newBudget,
|
||||
spent: 0,
|
||||
expenses: [],
|
||||
};
|
||||
const insertBudgetMock = jest.fn();
|
||||
insertBudgetMock.mockImplementation((budgetSummary) => budgetSummary);
|
||||
|
@ -23,7 +22,7 @@ describe("budgetService", () => {
|
|||
|
||||
// THEN
|
||||
expect(insertedBudgetSummary).toEqual(
|
||||
expect.objectContaining(expectedBudgetSummary)
|
||||
expect.objectContaining(expectedBudget)
|
||||
);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -1,3 +1,7 @@
|
|||
# The terraform code in this repo is based on the official tutorial from the following link
|
||||
# https://cloud.google.com/blog/topics/developers-practitioners/easy-deployment-mean-stack-w-mongodb-atlas-cloud-run-and-hashicorp-terraform
|
||||
# The rest of the steps can be followed up from there.
|
||||
|
||||
provider "mongodbatlas" {
|
||||
public_key = var.atlas_pub_key
|
||||
private_key = var.atlas_priv_key
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
# The terraform code in this repo is based on the official tutorial from the following link
|
||||
# https://cloud.google.com/blog/topics/developers-practitioners/easy-deployment-mean-stack-w-mongodb-atlas-cloud-run-and-hashicorp-terraform
|
||||
# The rest of the steps can be followed up from there.
|
||||
resource "google_project_service" "ci_cd" {
|
||||
project = google_project.prj.name
|
||||
service = "${each.value}.googleapis.com"
|
||||
|
|
|
@ -1,3 +1,7 @@
|
|||
# The terraform code in this repo is based on the official tutorial from the following link
|
||||
# https://cloud.google.com/blog/topics/developers-practitioners/easy-deployment-mean-stack-w-mongodb-atlas-cloud-run-and-hashicorp-terraform
|
||||
# The rest of the steps can be followed up from there.
|
||||
|
||||
provider "google" {}
|
||||
|
||||
resource "google_project" "prj" {
|
||||
|
|
|
@ -1,3 +1,7 @@
|
|||
# The terraform code in this repo is based on the official tutorial from the following link
|
||||
# https://cloud.google.com/blog/topics/developers-practitioners/easy-deployment-mean-stack-w-mongodb-atlas-cloud-run-and-hashicorp-terraform
|
||||
# The rest of the steps can be followed up from there.
|
||||
|
||||
###-----------------------------------------------------------------------------
|
||||
### configure terraform
|
||||
###-----------------------------------------------------------------------------
|
||||
|
|
|
@ -1,3 +1,7 @@
|
|||
# The terraform code in this repo is based on the official tutorial from the following link
|
||||
# https://cloud.google.com/blog/topics/developers-practitioners/easy-deployment-mean-stack-w-mongodb-atlas-cloud-run-and-hashicorp-terraform
|
||||
# The rest of the steps can be followed up from there.
|
||||
|
||||
output "app_url" {
|
||||
value = google_cloud_run_service.app.status[0].url
|
||||
}
|
||||
|
|
|
@ -1,3 +1,7 @@
|
|||
# The terraform code in this repo is based on the official tutorial from the following link
|
||||
# https://cloud.google.com/blog/topics/developers-practitioners/easy-deployment-mean-stack-w-mongodb-atlas-cloud-run-and-hashicorp-terraform
|
||||
# The rest of the steps can be followed up from there.
|
||||
|
||||
###-----------------------------------------------------------------------------
|
||||
### general config
|
||||
###-----------------------------------------------------------------------------
|
||||
|
|
Loading…
Reference in a new issue