test: add unit tests for DAOs
This commit is contained in:
73
src/app/dao/ChainDAO.spec.ts
Normal file
73
src/app/dao/ChainDAO.spec.ts
Normal file
@@ -0,0 +1,73 @@
|
|||||||
|
import { TestBed } from '@angular/core/testing';
|
||||||
|
import { ChainDAO } from './ChainDAO';
|
||||||
|
import { Sqlite } from '../services/sqlite';
|
||||||
|
import { vi } from 'vitest';
|
||||||
|
import { QueryResult } from '../types/sqlite.type';
|
||||||
|
import { Chain } from '../models/Chain';
|
||||||
|
|
||||||
|
describe('ChainDAO', () => {
|
||||||
|
let service: ChainDAO;
|
||||||
|
let sqlite: Partial<Sqlite>;
|
||||||
|
let CHAIN_MOCK: Chain;
|
||||||
|
let RESULTS_MOCK: QueryResult<Chain>;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
CHAIN_MOCK = new Chain('mock', 'mock.png', 1);
|
||||||
|
RESULTS_MOCK = { rows: [CHAIN_MOCK] };
|
||||||
|
|
||||||
|
sqlite = {
|
||||||
|
executeQuery: vi.fn().mockResolvedValue(RESULTS_MOCK),
|
||||||
|
};
|
||||||
|
|
||||||
|
TestBed.configureTestingModule({
|
||||||
|
providers: [{ provide: Sqlite, useValue: sqlite }],
|
||||||
|
});
|
||||||
|
|
||||||
|
service = TestBed.inject(ChainDAO);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should be created', () => {
|
||||||
|
expect(service).toBeTruthy();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should receive mapped results on findAll', async () => {
|
||||||
|
const result = await service.findAll();
|
||||||
|
if (result.length > 0) {
|
||||||
|
expect(result[0]).toEqual(CHAIN_MOCK);
|
||||||
|
} else {
|
||||||
|
test.fails('Expected mock response to contain at least one value');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should receive mapped results on findBy', async () => {
|
||||||
|
const result = await service.findBy({ id: CHAIN_MOCK.id, name: CHAIN_MOCK.name });
|
||||||
|
if (result.length > 0) {
|
||||||
|
expect(result[0]).toEqual(CHAIN_MOCK);
|
||||||
|
} else {
|
||||||
|
test.fails('Expected mock response to contain at least one value');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should call executeQuery with object fields on insert', async () => {
|
||||||
|
const expectedSql = 'INSERT INTO chain ( name, image, id ) VALUES ( ?, ?, ? );';
|
||||||
|
const expectedParams: any[] = [];
|
||||||
|
for (let key in CHAIN_MOCK) {
|
||||||
|
expectedParams.push(CHAIN_MOCK[<keyof Chain>key]);
|
||||||
|
}
|
||||||
|
await service.insert(CHAIN_MOCK);
|
||||||
|
expect(sqlite.executeQuery).toHaveBeenCalledExactlyOnceWith(expectedSql, expectedParams);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should call executeQuery with object fields and where values on update', async () => {
|
||||||
|
const expectedParams: any[] = [];
|
||||||
|
CHAIN_MOCK.name = 'Updated mock';
|
||||||
|
for (let key in CHAIN_MOCK) {
|
||||||
|
expectedParams.push(CHAIN_MOCK[<keyof Chain>key]);
|
||||||
|
}
|
||||||
|
const WHERE_MOCK: Partial<Chain> = { id: 1 };
|
||||||
|
expectedParams.push(WHERE_MOCK.id);
|
||||||
|
const expectedSql = 'UPDATE chain SET name = ?, image = ?, id = ? WHERE id = ? ;';
|
||||||
|
await service.update(CHAIN_MOCK, WHERE_MOCK);
|
||||||
|
expect(sqlite.executeQuery).toHaveBeenCalledExactlyOnceWith(expectedSql, expectedParams);
|
||||||
|
});
|
||||||
|
});
|
||||||
76
src/app/dao/EstablishmentDAO.spec.ts
Normal file
76
src/app/dao/EstablishmentDAO.spec.ts
Normal file
@@ -0,0 +1,76 @@
|
|||||||
|
import { TestBed } from '@angular/core/testing';
|
||||||
|
import { EstablishmentDAO } from './EstablishmentDAO';
|
||||||
|
import { Sqlite } from '../services/sqlite';
|
||||||
|
import { Establishment } from '../models/Establishment';
|
||||||
|
import { Chain } from '../models/Chain';
|
||||||
|
import { EstablishmentQueryResult } from '../types/sqlite.type';
|
||||||
|
|
||||||
|
describe('EstablishmentDAO', () => {
|
||||||
|
let service: EstablishmentDAO;
|
||||||
|
let sqlite: Partial<Sqlite>;
|
||||||
|
let ESTABLISHMENT_MOCK: Establishment;
|
||||||
|
let QUERY_RESULT_MOCK: EstablishmentQueryResult;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
QUERY_RESULT_MOCK = {
|
||||||
|
address: 'mock street',
|
||||||
|
image: 'mock.jpg',
|
||||||
|
name: 'mock',
|
||||||
|
chain_id: 1,
|
||||||
|
id: 1,
|
||||||
|
};
|
||||||
|
ESTABLISHMENT_MOCK = new Establishment(
|
||||||
|
new Chain(QUERY_RESULT_MOCK.name, QUERY_RESULT_MOCK.image, QUERY_RESULT_MOCK.chain_id),
|
||||||
|
QUERY_RESULT_MOCK.address,
|
||||||
|
QUERY_RESULT_MOCK.id,
|
||||||
|
);
|
||||||
|
|
||||||
|
sqlite = {
|
||||||
|
executeQuery: vi.fn().mockResolvedValue({ rows: [QUERY_RESULT_MOCK] }),
|
||||||
|
};
|
||||||
|
|
||||||
|
TestBed.configureTestingModule({
|
||||||
|
providers: [{ provide: Sqlite, useValue: sqlite }],
|
||||||
|
});
|
||||||
|
|
||||||
|
service = TestBed.inject(EstablishmentDAO);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should be created', () => {
|
||||||
|
expect(service).toBeTruthy();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should receive mapped results on findAll', async () => {
|
||||||
|
const result = await service.findAll();
|
||||||
|
if (result.length > 0) {
|
||||||
|
expect(result[0]).toEqual(ESTABLISHMENT_MOCK);
|
||||||
|
} else {
|
||||||
|
test.fails('Expected mock response to contain at least one value');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should receive mapped results on findBy', async () => {
|
||||||
|
const result = await service.findBy({ id: 1 });
|
||||||
|
if (result.length > 0) {
|
||||||
|
expect(result[0]).toEqual(ESTABLISHMENT_MOCK);
|
||||||
|
} else {
|
||||||
|
test.fails('Expected mock response to contain at least one value');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should call executeQuery with object fields on insert', async () => {
|
||||||
|
sqlite.executeQuery = vi.fn().mockResolvedValue({ rows: [] });
|
||||||
|
const expectedSql = 'INSERT INTO establishment ( address, chain_id ) VALUES ( ?, ? );';
|
||||||
|
const expectedParams = [ESTABLISHMENT_MOCK.address, ESTABLISHMENT_MOCK.chain.id];
|
||||||
|
ESTABLISHMENT_MOCK.id = undefined;
|
||||||
|
await service.insert(ESTABLISHMENT_MOCK);
|
||||||
|
expect(sqlite.executeQuery).toHaveBeenCalledExactlyOnceWith(expectedSql, expectedParams);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should throw if toDB is called with a chain that has no id', async () => {
|
||||||
|
sqlite.executeQuery = vi.fn().mockResolvedValue({ rows: [] });
|
||||||
|
ESTABLISHMENT_MOCK.id = undefined;
|
||||||
|
ESTABLISHMENT_MOCK.chain.id = undefined;
|
||||||
|
expect(service.insert(ESTABLISHMENT_MOCK)).rejects.toThrow();
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -3,6 +3,7 @@ import { Establishment } from '../models/Establishment';
|
|||||||
import { Chain } from '../models/Chain';
|
import { Chain } from '../models/Chain';
|
||||||
import { DBEstablishment } from '../models/db/DBEstablishment';
|
import { DBEstablishment } from '../models/db/DBEstablishment';
|
||||||
import { ComposedDAO } from './ComposedDAO';
|
import { ComposedDAO } from './ComposedDAO';
|
||||||
|
import { EstablishmentQueryResult } from '../types/sqlite.type';
|
||||||
|
|
||||||
@Injectable({
|
@Injectable({
|
||||||
providedIn: 'root',
|
providedIn: 'root',
|
||||||
@@ -16,7 +17,7 @@ export class EstablishmentDAO extends ComposedDAO<
|
|||||||
super(
|
super(
|
||||||
Establishment.name,
|
Establishment.name,
|
||||||
`SELECT e.id, e.address, chain_id, c.name, c.image FROM establishment e JOIN chain c ON c.id = chain_id;`,
|
`SELECT e.id, e.address, chain_id, c.name, c.image FROM establishment e JOIN chain c ON c.id = chain_id;`,
|
||||||
'e'
|
'e',
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -30,6 +31,3 @@ export class EstablishmentDAO extends ComposedDAO<
|
|||||||
return new Establishment(chain, qR.address, qR.id);
|
return new Establishment(chain, qR.address, qR.id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
type EstablishmentQueryResult = Omit<Establishment, 'chain'> &
|
|
||||||
Omit<Chain, 'id'> & { id: number; chain_id: number };
|
|
||||||
|
|||||||
46
src/app/dao/ProductDAO.spec.ts
Normal file
46
src/app/dao/ProductDAO.spec.ts
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
import { TestBed } from '@angular/core/testing';
|
||||||
|
import { ProductDAO } from './ProductDAO';
|
||||||
|
import { Sqlite } from '../services/sqlite';
|
||||||
|
import { Product } from '../models/Product';
|
||||||
|
|
||||||
|
describe('ProductDAO', () => {
|
||||||
|
let service: ProductDAO;
|
||||||
|
let sqlite: Partial<Sqlite>;
|
||||||
|
|
||||||
|
let PRODUCT_MOCK: Product;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
PRODUCT_MOCK = new Product('12121112', 'mock', 'mock.jpg', 1);
|
||||||
|
|
||||||
|
sqlite = {
|
||||||
|
executeQuery: vi.fn().mockResolvedValue({ rows: [PRODUCT_MOCK] }),
|
||||||
|
};
|
||||||
|
|
||||||
|
TestBed.configureTestingModule({
|
||||||
|
providers: [{ provide: Sqlite, useValue: sqlite }],
|
||||||
|
});
|
||||||
|
|
||||||
|
service = TestBed.inject(ProductDAO);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should be created', () => {
|
||||||
|
expect(service).toBeTruthy();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should receive mapped results on findAll', async () => {
|
||||||
|
const result = await service.findAll();
|
||||||
|
if (result.length > 0) {
|
||||||
|
expect(result[0]).toEqual(PRODUCT_MOCK);
|
||||||
|
} else {
|
||||||
|
test.fails('Expected mock response to contain at least one value');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should call executeQuery with object fields on insert', async () => {
|
||||||
|
PRODUCT_MOCK.id = undefined;
|
||||||
|
const expectedSql = 'INSERT INTO product ( barcode, name, image ) VALUES ( ?, ?, ? );';
|
||||||
|
const expectedParams: any[] = [PRODUCT_MOCK.barcode, PRODUCT_MOCK.name, PRODUCT_MOCK.image];
|
||||||
|
await service.insert(PRODUCT_MOCK);
|
||||||
|
expect(sqlite.executeQuery).toHaveBeenCalledExactlyOnceWith(expectedSql, expectedParams);
|
||||||
|
});
|
||||||
|
});
|
||||||
86
src/app/dao/ProductEstablishmentDAO.spec.ts
Normal file
86
src/app/dao/ProductEstablishmentDAO.spec.ts
Normal file
@@ -0,0 +1,86 @@
|
|||||||
|
import { TestBed } from '@angular/core/testing';
|
||||||
|
import { ProductEstablishmentDAO } from './ProductEstablishmentDAO';
|
||||||
|
import { Sqlite } from '../services/sqlite';
|
||||||
|
import { ProductEstablishment } from '../models/ProductEstablisment';
|
||||||
|
import { Product } from '../models/Product';
|
||||||
|
import { Establishment } from '../models/Establishment';
|
||||||
|
import { Chain } from '../models/Chain';
|
||||||
|
import { ProductEstablishmentQueryResult } from '../types/sqlite.type';
|
||||||
|
|
||||||
|
describe('ProductEstablishmentDAO', () => {
|
||||||
|
let service: ProductEstablishmentDAO;
|
||||||
|
let sqlite: Partial<Sqlite>;
|
||||||
|
|
||||||
|
let PRODUCT_ESTABLISHMENT_MOCK: ProductEstablishment;
|
||||||
|
let PRODUCT_ESTABLISHMENT_QUERY_RESULT: ProductEstablishmentQueryResult;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
PRODUCT_ESTABLISHMENT_MOCK = new ProductEstablishment(
|
||||||
|
new Product('121212', 'mock', 'mock.jpg', 1),
|
||||||
|
new Establishment(new Chain('mock', 'mock.png', 1), 'mock street', 1),
|
||||||
|
1,
|
||||||
|
);
|
||||||
|
PRODUCT_ESTABLISHMENT_QUERY_RESULT = {
|
||||||
|
address: PRODUCT_ESTABLISHMENT_MOCK.establishment.address,
|
||||||
|
barcode: PRODUCT_ESTABLISHMENT_MOCK.product.barcode,
|
||||||
|
chain_id: PRODUCT_ESTABLISHMENT_MOCK.establishment.chain.id!,
|
||||||
|
chain_image: PRODUCT_ESTABLISHMENT_MOCK.establishment.chain.image,
|
||||||
|
chain_name: PRODUCT_ESTABLISHMENT_MOCK.establishment.chain.name,
|
||||||
|
establishment_id: PRODUCT_ESTABLISHMENT_MOCK.establishment.id!,
|
||||||
|
id: PRODUCT_ESTABLISHMENT_MOCK.id!,
|
||||||
|
product_id: PRODUCT_ESTABLISHMENT_MOCK.product.id!,
|
||||||
|
product_image: PRODUCT_ESTABLISHMENT_MOCK.product.image,
|
||||||
|
product_name: PRODUCT_ESTABLISHMENT_MOCK.product.name,
|
||||||
|
};
|
||||||
|
|
||||||
|
sqlite = {
|
||||||
|
executeQuery: vi.fn().mockResolvedValue({ rows: [PRODUCT_ESTABLISHMENT_QUERY_RESULT] }),
|
||||||
|
};
|
||||||
|
|
||||||
|
TestBed.configureTestingModule({
|
||||||
|
providers: [{ provide: Sqlite, useValue: sqlite }],
|
||||||
|
});
|
||||||
|
|
||||||
|
service = TestBed.inject(ProductEstablishmentDAO);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should be created', () => {
|
||||||
|
expect(PRODUCT_ESTABLISHMENT_MOCK).toBeTruthy();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should receive mapped results on findAll', async () => {
|
||||||
|
const result = await service.findAll();
|
||||||
|
if (result.length > 0) {
|
||||||
|
expect(result[0]).toEqual(PRODUCT_ESTABLISHMENT_MOCK);
|
||||||
|
} else {
|
||||||
|
test.fails('Expected mock response to contain at least one value');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should call executeQuery with object fields on insert', async () => {
|
||||||
|
sqlite.executeQuery = vi.fn().mockResolvedValue({ rows: [] });
|
||||||
|
const expectedSql =
|
||||||
|
'INSERT INTO product_establishment ( product_id, establishment_id ) VALUES ( ?, ? );';
|
||||||
|
const expectedParams: any[] = [
|
||||||
|
PRODUCT_ESTABLISHMENT_MOCK.product.id,
|
||||||
|
PRODUCT_ESTABLISHMENT_MOCK.establishment.id,
|
||||||
|
];
|
||||||
|
PRODUCT_ESTABLISHMENT_MOCK.id = undefined;
|
||||||
|
await service.insert(PRODUCT_ESTABLISHMENT_MOCK);
|
||||||
|
expect(sqlite.executeQuery).toHaveBeenCalledExactlyOnceWith(expectedSql, expectedParams);
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('toDB', () => {
|
||||||
|
it('should throw if toDB is called with a product that has no id', async () => {
|
||||||
|
sqlite.executeQuery = vi.fn().mockResolvedValue({ rows: [] });
|
||||||
|
PRODUCT_ESTABLISHMENT_MOCK.product.id = undefined;
|
||||||
|
expect(service.insert(PRODUCT_ESTABLISHMENT_MOCK)).rejects.toThrow();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should throw if toDB is called with a establishmen that has no id', async () => {
|
||||||
|
sqlite.executeQuery = vi.fn().mockResolvedValue({ rows: [] });
|
||||||
|
PRODUCT_ESTABLISHMENT_MOCK.establishment.id = undefined;
|
||||||
|
expect(service.insert(PRODUCT_ESTABLISHMENT_MOCK)).rejects.toThrow();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -5,6 +5,7 @@ import { ProductEstablishment } from '../models/ProductEstablisment';
|
|||||||
import { Chain } from '../models/Chain';
|
import { Chain } from '../models/Chain';
|
||||||
import { DBProductEstablishment } from '../models/db/DBProductEstablishment';
|
import { DBProductEstablishment } from '../models/db/DBProductEstablishment';
|
||||||
import { ComposedDAO } from './ComposedDAO';
|
import { ComposedDAO } from './ComposedDAO';
|
||||||
|
import { ProductEstablishmentQueryResult } from '../types/sqlite.type';
|
||||||
|
|
||||||
@Injectable({
|
@Injectable({
|
||||||
providedIn: 'root',
|
providedIn: 'root',
|
||||||
@@ -23,7 +24,7 @@ export class ProductEstablishmentDAO extends ComposedDAO<
|
|||||||
JOIN product p ON p.id = pe.product_id
|
JOIN product p ON p.id = pe.product_id
|
||||||
JOIN establishment e ON e.id = pe.establishment_id
|
JOIN establishment e ON e.id = pe.establishment_id
|
||||||
JOIN chain c ON c.id = e.chain_id;`,
|
JOIN chain c ON c.id = e.chain_id;`,
|
||||||
'pe'
|
'pe',
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -40,16 +41,3 @@ export class ProductEstablishmentDAO extends ComposedDAO<
|
|||||||
return new ProductEstablishment(product, establishment, qR.id);
|
return new ProductEstablishment(product, establishment, qR.id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
type ProductEstablishmentQueryResult = {
|
|
||||||
address: string;
|
|
||||||
barcode: string;
|
|
||||||
chain_id: number;
|
|
||||||
chain_image: string | null;
|
|
||||||
chain_name: string;
|
|
||||||
establishment_id: number;
|
|
||||||
id: number;
|
|
||||||
product_id: number;
|
|
||||||
product_image: string | null;
|
|
||||||
product_name: string;
|
|
||||||
};
|
|
||||||
|
|||||||
95
src/app/dao/PurchaseDAO.spec.ts
Normal file
95
src/app/dao/PurchaseDAO.spec.ts
Normal file
@@ -0,0 +1,95 @@
|
|||||||
|
import { TestBed } from '@angular/core/testing';
|
||||||
|
import { PurchaseDAO } from './PurchaseDAO';
|
||||||
|
import { Sqlite } from '../services/sqlite';
|
||||||
|
import { Purchase } from '../models/Purchase';
|
||||||
|
import { Establishment } from '../models/Establishment';
|
||||||
|
import { Chain } from '../models/Chain';
|
||||||
|
import { Product } from '../models/Product';
|
||||||
|
import { PurchaseQueryResult } from '../types/sqlite.type';
|
||||||
|
|
||||||
|
describe('PurchaseDAO', () => {
|
||||||
|
let service: PurchaseDAO;
|
||||||
|
let sqlite: Partial<Sqlite>;
|
||||||
|
|
||||||
|
let PURCHASE_MOCK: Purchase;
|
||||||
|
let PURCHASE_QUERY_RESULT_MOCK: PurchaseQueryResult;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
PURCHASE_MOCK = new Purchase(
|
||||||
|
new Establishment(new Chain('mock', 'mock.jpg', 1), 'mock street', 1),
|
||||||
|
new Product('1212112', 'mock', 'mock.png', 1),
|
||||||
|
1245.55,
|
||||||
|
3,
|
||||||
|
Date.now(),
|
||||||
|
1,
|
||||||
|
);
|
||||||
|
PURCHASE_QUERY_RESULT_MOCK = {
|
||||||
|
address: PURCHASE_MOCK.establishment.address,
|
||||||
|
barcode: PURCHASE_MOCK.product.barcode,
|
||||||
|
chain_id: PURCHASE_MOCK.establishment.chain.id!,
|
||||||
|
chain_image: PURCHASE_MOCK.establishment.chain.image,
|
||||||
|
chain_name: PURCHASE_MOCK.establishment.chain.name,
|
||||||
|
date: PURCHASE_MOCK.date,
|
||||||
|
establishment_id: PURCHASE_MOCK.establishment.id!,
|
||||||
|
id: PURCHASE_MOCK.id!,
|
||||||
|
price: PURCHASE_MOCK.price,
|
||||||
|
product_id: PURCHASE_MOCK.product.id!,
|
||||||
|
product_image: PURCHASE_MOCK.product.image,
|
||||||
|
product_name: PURCHASE_MOCK.product.name,
|
||||||
|
quantity: PURCHASE_MOCK.quantity,
|
||||||
|
};
|
||||||
|
|
||||||
|
sqlite = {
|
||||||
|
executeQuery: vi.fn().mockResolvedValue({ rows: [PURCHASE_QUERY_RESULT_MOCK] }),
|
||||||
|
};
|
||||||
|
|
||||||
|
TestBed.configureTestingModule({
|
||||||
|
providers: [{ provide: Sqlite, useValue: sqlite }],
|
||||||
|
});
|
||||||
|
|
||||||
|
service = TestBed.inject(PurchaseDAO);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should be created', () => {
|
||||||
|
expect(PURCHASE_MOCK).toBeTruthy();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should receive mapped results on findAll', async () => {
|
||||||
|
const result = await service.findAll();
|
||||||
|
if (result.length > 0) {
|
||||||
|
expect(result[0]).toEqual(PURCHASE_MOCK);
|
||||||
|
} else {
|
||||||
|
test.fails('Expected mock response to contain at least one value');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should call executeQuery with object fields on insert', async () => {
|
||||||
|
sqlite.executeQuery = vi.fn().mockResolvedValue({ rows: [] });
|
||||||
|
const expectedSql =
|
||||||
|
'INSERT INTO purchase ( establishment_id, product_id, date, price, quantity ) VALUES ( ?, ?, ?, ?, ? );';
|
||||||
|
const expectedParams: any[] = [
|
||||||
|
PURCHASE_MOCK.establishment.id,
|
||||||
|
PURCHASE_MOCK.product.id,
|
||||||
|
PURCHASE_MOCK.date,
|
||||||
|
PURCHASE_MOCK.price * 100,
|
||||||
|
PURCHASE_MOCK.quantity,
|
||||||
|
];
|
||||||
|
PURCHASE_MOCK.id = undefined;
|
||||||
|
await service.insert(PURCHASE_MOCK);
|
||||||
|
expect(sqlite.executeQuery).toHaveBeenCalledExactlyOnceWith(expectedSql, expectedParams);
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('toDB', () => {
|
||||||
|
it('should throw if toDB is called with a establishmen that has no id', async () => {
|
||||||
|
sqlite.executeQuery = vi.fn().mockResolvedValue({ rows: [] });
|
||||||
|
PURCHASE_MOCK.establishment.id = undefined;
|
||||||
|
expect(service.insert(PURCHASE_MOCK)).rejects.toThrow();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should throw if toDB is called with a product that has no id', async () => {
|
||||||
|
sqlite.executeQuery = vi.fn().mockResolvedValue({ rows: [] });
|
||||||
|
PURCHASE_MOCK.product.id = undefined;
|
||||||
|
expect(service.insert(PURCHASE_MOCK)).rejects.toThrow();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -5,6 +5,7 @@ import { Establishment } from '../models/Establishment';
|
|||||||
import { Chain } from '../models/Chain';
|
import { Chain } from '../models/Chain';
|
||||||
import { Product } from '../models/Product';
|
import { Product } from '../models/Product';
|
||||||
import { ComposedDAO } from './ComposedDAO';
|
import { ComposedDAO } from './ComposedDAO';
|
||||||
|
import { PurchaseQueryResult } from '../types/sqlite.type';
|
||||||
|
|
||||||
@Injectable({
|
@Injectable({
|
||||||
providedIn: 'root',
|
providedIn: 'root',
|
||||||
@@ -21,7 +22,7 @@ export class PurchaseDAO extends ComposedDAO<Purchase, DBPurchase, PurchaseQuery
|
|||||||
JOIN product pr ON pr.id = p.product_id
|
JOIN product pr ON pr.id = p.product_id
|
||||||
JOIN establishment e ON e.id = p.establishment_id
|
JOIN establishment e ON e.id = p.establishment_id
|
||||||
JOIN chain c ON c.id = e.chain_id;`,
|
JOIN chain c ON c.id = e.chain_id;`,
|
||||||
'e'
|
'e',
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -34,7 +35,7 @@ export class PurchaseDAO extends ComposedDAO<Purchase, DBPurchase, PurchaseQuery
|
|||||||
model.date,
|
model.date,
|
||||||
model.price * 100,
|
model.price * 100,
|
||||||
model.quantity,
|
model.quantity,
|
||||||
model.id
|
model.id,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -45,19 +46,3 @@ export class PurchaseDAO extends ComposedDAO<Purchase, DBPurchase, PurchaseQuery
|
|||||||
return new Purchase(establishment, product, qR.price / 100, qR.quantity, qR.date, qR.id);
|
return new Purchase(establishment, product, qR.price / 100, qR.quantity, qR.date, qR.id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
type PurchaseQueryResult = {
|
|
||||||
id: number;
|
|
||||||
price: number;
|
|
||||||
quantity: number;
|
|
||||||
date: number;
|
|
||||||
establishment_id: number;
|
|
||||||
product_id: number;
|
|
||||||
barcode: string;
|
|
||||||
product_image: string;
|
|
||||||
product_name: string;
|
|
||||||
address: string;
|
|
||||||
chain_id: number;
|
|
||||||
chain_image: string;
|
|
||||||
chain_name: string;
|
|
||||||
};
|
|
||||||
|
|||||||
@@ -1,2 +1,37 @@
|
|||||||
|
import { Chain } from '../models/Chain';
|
||||||
|
import { Establishment } from '../models/Establishment';
|
||||||
|
|
||||||
export type QueryResult<T> = { rows: T[] };
|
export type QueryResult<T> = { rows: T[] };
|
||||||
export type BatchOp = [string, any[]];
|
export type BatchOp = [string, any[]];
|
||||||
|
|
||||||
|
export type PurchaseQueryResult = {
|
||||||
|
id: number;
|
||||||
|
price: number;
|
||||||
|
quantity: number;
|
||||||
|
date: number;
|
||||||
|
establishment_id: number;
|
||||||
|
product_id: number;
|
||||||
|
barcode: string;
|
||||||
|
product_image: string | null;
|
||||||
|
product_name: string;
|
||||||
|
address: string;
|
||||||
|
chain_id: number;
|
||||||
|
chain_image: string | null;
|
||||||
|
chain_name: string | null;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type ProductEstablishmentQueryResult = {
|
||||||
|
address: string;
|
||||||
|
barcode: string;
|
||||||
|
chain_id: number;
|
||||||
|
chain_image: string | null;
|
||||||
|
chain_name: string | null;
|
||||||
|
establishment_id: number;
|
||||||
|
id: number;
|
||||||
|
product_id: number;
|
||||||
|
product_image: string | null;
|
||||||
|
product_name: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type EstablishmentQueryResult = Omit<Establishment, 'chain'> &
|
||||||
|
Omit<Chain, 'id'> & { id: number; chain_id: number };
|
||||||
|
|||||||
Reference in New Issue
Block a user