/* eslint max-len: ["error", { "code": 150 }]*/ const models = require('vn-loopback/server/server').models; const LoopBackContext = require('loopback-context'); describe('sale model ', () => { const ctx = { req: { accessToken: {userId: 9}, headers: {origin: 'localhost:5000'}, __: () => {} } }; function getActiveCtx(userId) { return { active: { accessToken: {userId}, http: { req: { headers: {origin: 'http://localhost'} } } } }; } describe('quantity field ', () => { it('should add quantity if the quantity is greater than it should be and is role advanced', async() => { const saleId = 17; const buyerId = 35; const ctx = { req: { accessToken: {userId: buyerId}, headers: {origin: 'localhost:5000'}, __: () => {} } }; const tx = await models.Sale.beginTransaction({}); spyOn(LoopBackContext, 'getCurrentContext').and.returnValue(getActiveCtx(buyerId)); spyOn(models.Sale, 'rawSql').and.callFake((sqlStatement, params, options) => { if (sqlStatement.includes('catalog_calcFromItem')) { sqlStatement = `CREATE OR REPLACE TEMPORARY TABLE tmp.ticketCalculateItem ENGINE = MEMORY SELECT 100 as available;`; params = null; } return models.Ticket.rawSql(sqlStatement, params, options); }); try { const options = {transaction: tx}; const isRoleAdvanced = await models.ACL.checkAccessAcl(ctx, 'Ticket', 'isRoleAdvanced', '*'); expect(isRoleAdvanced).toEqual(true); const originalLine = await models.Sale.findOne({where: {id: saleId}, fields: ['quantity']}, options); expect(originalLine.quantity).toEqual(30); const newQuantity = originalLine.quantity + 1; await models.Sale.updateQuantity(ctx, saleId, newQuantity, options); const modifiedLine = await models.Sale.findOne({where: {id: saleId}, fields: ['quantity']}, options); expect(modifiedLine.quantity).toEqual(newQuantity); await tx.rollback(); } catch (e) { await tx.rollback(); throw e; } }); it('should update the quantity of a given sale current line', async() => { spyOn(LoopBackContext, 'getCurrentContext').and.returnValue(getActiveCtx(9)); const tx = await models.Sale.beginTransaction({}); const saleId = 25; const newQuantity = 4; try { const options = {transaction: tx}; const originalLine = await models.Sale.findOne({where: {id: saleId}, fields: ['quantity']}, options); expect(originalLine.quantity).toEqual(20); await models.Sale.updateQuantity(ctx, saleId, newQuantity, options); const modifiedLine = await models.Sale.findOne({where: {id: saleId}, fields: ['quantity']}, options); expect(modifiedLine.quantity).toEqual(newQuantity); await tx.rollback(); } catch (e) { await tx.rollback(); throw e; } }); it('should throw an error if the quantity is negative and it is not a refund ticket', async() => { const ctx = { req: { accessToken: {userId: 1}, headers: {origin: 'localhost:5000'}, __: () => {} } }; spyOn(LoopBackContext, 'getCurrentContext').and.returnValue(getActiveCtx(1)); const saleId = 17; const newQuantity = -10; const tx = await models.Sale.beginTransaction({}); let error; try { const options = {transaction: tx}; await models.Sale.updateQuantity(ctx, saleId, newQuantity, options); await tx.rollback(); } catch (e) { await tx.rollback(); error = e; } expect(error).toEqual(new Error('You can only add negative amounts in refund tickets')); }); it('should update a negative quantity when is a ticket refund', async() => { spyOn(LoopBackContext, 'getCurrentContext').and.returnValue(getActiveCtx(9)); const tx = await models.Sale.beginTransaction({}); const saleId = 32; const newQuantity = -10; try { const options = {transaction: tx}; await models.Sale.updateQuantity(ctx, saleId, newQuantity, options); const modifiedLine = await models.Sale.findOne({where: {id: saleId}, fields: ['quantity']}, options); expect(modifiedLine.quantity).toEqual(newQuantity); await tx.rollback(); } catch (e) { await tx.rollback(); throw e; } }); it('should throw an error if the quantity is less than the minimum quantity of the item', async() => { const ctx = { req: { accessToken: {userId: 1}, headers: {origin: 'localhost:5000'}, __: () => {} } }; spyOn(LoopBackContext, 'getCurrentContext').and.returnValue(getActiveCtx(1)); const tx = await models.Sale.beginTransaction({}); const itemId = 2; const saleId = 17; const minQuantity = 30; const newQuantity = minQuantity - 1; let error; try { const options = {transaction: tx}; const item = await models.Item.findById(itemId, null, options); await item.updateAttribute('minQuantity', minQuantity, options); spyOn(models.Sale, 'rawSql').and.callFake((sqlStatement, params, options) => { if (sqlStatement.includes('catalog_calcFromItem')) { sqlStatement = `CREATE OR REPLACE TEMPORARY TABLE tmp.ticketCalculateItem ENGINE = MEMORY SELECT 100 as available;`; params = null; } return models.Ticket.rawSql(sqlStatement, params, options); }); await models.Sale.updateQuantity(ctx, saleId, newQuantity, options); await tx.rollback(); } catch (e) { await tx.rollback(); error = e; } expect(error).toEqual(new Error('The amount cannot be less than the minimum')); }); it('should change quantity if has minimum quantity and new quantity is equal than item available', async() => { const ctx = { req: { accessToken: {userId: 1}, headers: {origin: 'localhost:5000'}, __: () => {} } }; spyOn(LoopBackContext, 'getCurrentContext').and.returnValue(getActiveCtx(1)); const tx = await models.Sale.beginTransaction({}); const itemId = 2; const saleId = 17; const minQuantity = 30; const newQuantity = minQuantity - 1; try { const options = {transaction: tx}; const item = await models.Item.findById(itemId, null, options); await item.updateAttribute('minQuantity', minQuantity, options); spyOn(models.Sale, 'rawSql').and.callFake((sqlStatement, params, options) => { if (sqlStatement.includes('catalog_calcFromItem')) { sqlStatement = `CREATE OR REPLACE TEMPORARY TABLE tmp.ticketCalculateItem ENGINE = MEMORY SELECT ${newQuantity} as available;`; params = null; } return models.Ticket.rawSql(sqlStatement, params, options); }); await models.Sale.updateQuantity(ctx, saleId, newQuantity, options); await tx.rollback(); } catch (e) { await tx.rollback(); throw e; } }); describe('newPrice', () => { it('should increase quantity if you have enough available and the new price is the same as the previous one', async() => { const ctx = { req: { accessToken: {userId: 1}, headers: {origin: 'localhost:5000'}, __: () => {} } }; spyOn(LoopBackContext, 'getCurrentContext').and.returnValue(getActiveCtx(1)); const tx = await models.Sale.beginTransaction({}); const itemId = 2; const saleId = 17; const minQuantity = 30; const newQuantity = 31; try { const options = {transaction: tx}; const item = await models.Item.findById(itemId, null, options); await item.updateAttribute('minQuantity', minQuantity, options); spyOn(models.Sale, 'rawSql').and.callFake((sqlStatement, params, options) => { if (sqlStatement.includes('catalog_calcFromItem')) { sqlStatement = ` CREATE OR REPLACE TEMPORARY TABLE tmp.ticketCalculateItem ENGINE = MEMORY SELECT ${newQuantity} as available; CREATE OR REPLACE TEMPORARY TABLE tmp.ticketComponentPrice ENGINE = MEMORY SELECT 1 as grouping, 7.07 as price;`; params = null; } return models.Ticket.rawSql(sqlStatement, params, options); }); await models.Sale.updateQuantity(ctx, saleId, newQuantity, options); await tx.rollback(); } catch (e) { await tx.rollback(); throw e; } }); it('should increase quantity when the new price is lower than the previous one', async() => { const ctx = { req: { accessToken: {userId: 1}, headers: {origin: 'localhost:5000'}, __: () => {} } }; spyOn(LoopBackContext, 'getCurrentContext').and.returnValue(getActiveCtx(1)); const tx = await models.Sale.beginTransaction({}); const itemId = 2; const saleId = 17; const minQuantity = 30; const newQuantity = 31; try { const options = {transaction: tx}; const item = await models.Item.findById(itemId, null, options); await item.updateAttribute('minQuantity', minQuantity, options); spyOn(models.Sale, 'rawSql').and.callFake((sqlStatement, params, options) => { if (sqlStatement.includes('catalog_calcFromItem')) { sqlStatement = ` CREATE OR REPLACE TEMPORARY TABLE tmp.ticketCalculateItem ENGINE = MEMORY SELECT ${newQuantity} as available; CREATE OR REPLACE TEMPORARY TABLE tmp.ticketComponentPrice ENGINE = MEMORY SELECT 1 as grouping, 1 as price;`; params = null; } return models.Ticket.rawSql(sqlStatement, params, options); }); await models.Sale.updateQuantity(ctx, saleId, newQuantity, options); await tx.rollback(); } catch (e) { await tx.rollback(); throw e; } }); it('should throw error when increase quantity and the new price is higher than the previous one', async() => { const ctx = { req: { accessToken: {userId: 1}, headers: {origin: 'localhost:5000'}, __: () => {} } }; spyOn(LoopBackContext, 'getCurrentContext').and.returnValue(getActiveCtx(1)); const tx = await models.Sale.beginTransaction({}); const itemId = 2; const saleId = 17; const minQuantity = 30; const newQuantity = 31; let error; try { const options = {transaction: tx}; const item = await models.Item.findById(itemId, null, options); await item.updateAttribute('minQuantity', minQuantity, options); spyOn(models.Sale, 'rawSql').and.callFake((sqlStatement, params, options) => { if (sqlStatement.includes('catalog_calcFromItem')) { sqlStatement = ` CREATE OR REPLACE TEMPORARY TABLE tmp.ticketCalculateItem ENGINE = MEMORY SELECT ${newQuantity} as available; CREATE OR REPLACE TEMPORARY TABLE tmp.ticketComponentPrice ENGINE = MEMORY SELECT 1 as grouping, 100000 as price;`; params = null; } return models.Ticket.rawSql(sqlStatement, params, options); }); await models.Sale.updateQuantity(ctx, saleId, newQuantity, options); await tx.rollback(); } catch (e) { await tx.rollback(); error = e; } expect(error).toEqual(new Error('The price of the item changed')); }); }); }); });