Merged in chore/add-tests-for-getCorporateChequePrice (pull request #3114)

chore: Add tests for getCorporateChequePrice

* Add tests for getRequestedAdditionalPrice

* simplify types

* Add tests for getCorporateChequePrice


Approved-by: Joakim Jäderberg
This commit is contained in:
Anton Gunnarsson
2025-11-12 08:33:14 +00:00
parent c3b71a05d9
commit 9fbbd3a91b
2 changed files with 929 additions and 13 deletions

View File

@@ -1,11 +1,14 @@
import { describe, expect, it } from "vitest"
import { CurrencyEnum } from "@scandic-hotels/common/constants/currency"
import { RoomPackageCodeEnum } from "@scandic-hotels/trpc/enums/roomFilter"
import {
getAdditionalPrice,
getCorporateChequePrice,
getRedemptionPrice,
getRegularPrice,
getRequestedAdditionalPrice,
getVoucherPrice,
} from "./helpers"
@@ -137,6 +140,900 @@ describe("getAdditionalPrice", () => {
})
})
type GetRequestedAdditionalPriceParams = Parameters<
typeof getRequestedAdditionalPrice
>
describe("getRequestedAdditionalPrice", () => {
it("should initialize requested object when missing and add cheques to price", () => {
const total: GetRequestedAdditionalPriceParams[0] = {
local: {
price: 100,
currency: CurrencyEnum.SEK,
},
}
const adults = 1
const nights = 1
const breakfast = undefined
const packages = null
const cheques = 5
const additionalPrice = 0
const additionalPriceCurrency = undefined
getRequestedAdditionalPrice(
total,
adults,
breakfast,
nights,
packages,
cheques,
additionalPrice,
additionalPriceCurrency
)
expect(total.requested).toEqual({
currency: CurrencyEnum.CC,
price: 5,
additionalPrice: 0,
})
})
it("should add to existing requested price", () => {
const total: GetRequestedAdditionalPriceParams[0] = {
local: {
price: 100,
currency: CurrencyEnum.SEK,
},
requested: {
currency: CurrencyEnum.CC,
price: 10,
},
}
const adults = 1
const nights = 1
const breakfast = undefined
const packages = null
const cheques = 5
const additionalPrice = 0
const additionalPriceCurrency = undefined
getRequestedAdditionalPrice(
total,
adults,
breakfast,
nights,
packages,
cheques,
additionalPrice,
additionalPriceCurrency
)
expect(total.requested?.price).toBe(15)
})
it("should calculate additional price with only additionalPrice parameter", () => {
const total: GetRequestedAdditionalPriceParams[0] = {
local: {
price: 100,
currency: CurrencyEnum.SEK,
},
}
const adults = 1
const nights = 1
const breakfast = undefined
const packages = null
const cheques = 0
const additionalPrice = 50
const additionalPriceCurrency = CurrencyEnum.EUR
getRequestedAdditionalPrice(
total,
adults,
breakfast,
nights,
packages,
cheques,
additionalPrice,
additionalPriceCurrency
)
expect(total.requested).toEqual({
currency: CurrencyEnum.CC,
price: 0,
additionalPrice: 50,
additionalPriceCurrency: CurrencyEnum.EUR,
})
})
it("should calculate additional price with breakfast", () => {
const total: GetRequestedAdditionalPriceParams[0] = {
local: {
price: 100,
currency: CurrencyEnum.SEK,
},
}
const adults = 2
const nights = 3
const breakfast = {
requestedPrice: {
price: 10,
currency: CurrencyEnum.EUR,
},
}
const packages = null
const cheques = 0
const additionalPrice = 0
const additionalPriceCurrency = undefined
getRequestedAdditionalPrice(
total,
adults,
breakfast,
nights,
packages,
cheques,
additionalPrice,
additionalPriceCurrency
)
expect(total.requested?.additionalPrice).toBe(60)
})
it("should calculate additional price with packages", () => {
const total: GetRequestedAdditionalPriceParams[0] = {
local: {
price: 100,
currency: CurrencyEnum.SEK,
},
}
const adults = 1
const nights = 1
const breakfast = undefined
const packages = [
{
code: RoomPackageCodeEnum.PET_ROOM,
description: "Package 1",
localPrice: {
totalPrice: 100,
currency: CurrencyEnum.SEK,
price: 100,
},
requestedPrice: {
totalPrice: 25,
currency: CurrencyEnum.EUR,
price: 25,
},
inventories: [],
itemCode: "PKG1",
},
{
code: RoomPackageCodeEnum.ALLERGY_ROOM,
description: "Package 2",
localPrice: {
totalPrice: 80,
currency: CurrencyEnum.SEK,
price: 80,
},
requestedPrice: {
totalPrice: 15,
currency: CurrencyEnum.EUR,
price: 15,
},
inventories: [],
itemCode: "PKG2",
},
]
const cheques = 0
const additionalPrice = 0
const additionalPriceCurrency = undefined
getRequestedAdditionalPrice(
total,
adults,
breakfast,
nights,
packages,
cheques,
additionalPrice,
additionalPriceCurrency
)
expect(total.requested?.additionalPrice).toBe(40)
})
it("should calculate combined price with breakfast, packages, and additionalPrice", () => {
const total: GetRequestedAdditionalPriceParams[0] = {
local: {
price: 100,
currency: CurrencyEnum.SEK,
},
}
const adults = 2
const nights = 2
const breakfast = {
requestedPrice: {
price: 10,
currency: CurrencyEnum.EUR,
},
}
const packages = [
{
code: RoomPackageCodeEnum.PET_ROOM,
description: "Package 1",
localPrice: {
totalPrice: 100,
currency: CurrencyEnum.SEK,
price: 100,
},
requestedPrice: {
totalPrice: 20,
currency: CurrencyEnum.EUR,
price: 20,
},
inventories: [],
itemCode: "PKG1",
},
]
const cheques = 3
const additionalPrice = 15
const additionalPriceCurrency = CurrencyEnum.EUR
getRequestedAdditionalPrice(
total,
adults,
breakfast,
nights,
packages,
cheques,
additionalPrice,
additionalPriceCurrency
)
expect(total.requested).toEqual({
currency: CurrencyEnum.CC,
price: 3,
additionalPrice: 75,
additionalPriceCurrency: CurrencyEnum.EUR,
})
})
it("should set currency from additionalPriceCurrency when provided", () => {
const total: GetRequestedAdditionalPriceParams[0] = {
local: {
price: 100,
currency: CurrencyEnum.SEK,
},
}
const adults = 1
const nights = 1
const breakfast = undefined
const packages = null
const cheques = 0
const additionalPrice = 50
const additionalPriceCurrency = CurrencyEnum.EUR
getRequestedAdditionalPrice(
total,
adults,
breakfast,
nights,
packages,
cheques,
additionalPrice,
additionalPriceCurrency
)
expect(total.requested?.additionalPriceCurrency).toBe(CurrencyEnum.EUR)
})
it("should set currency from packages when additionalPriceCurrency not provided", () => {
const total: GetRequestedAdditionalPriceParams[0] = {
local: {
price: 100,
currency: CurrencyEnum.SEK,
},
}
const adults = 1
const nights = 1
const breakfast = undefined
const packages = [
{
code: RoomPackageCodeEnum.PET_ROOM,
description: "Package 1",
localPrice: {
totalPrice: 100,
currency: CurrencyEnum.SEK,
price: 100,
},
requestedPrice: {
totalPrice: 20,
currency: CurrencyEnum.EUR,
price: 20,
},
inventories: [],
itemCode: "PKG1",
},
]
const cheques = 0
const additionalPrice = 0
const additionalPriceCurrency = undefined
getRequestedAdditionalPrice(
total,
adults,
breakfast,
nights,
packages,
cheques,
additionalPrice,
additionalPriceCurrency
)
expect(total.requested?.additionalPriceCurrency).toBe(CurrencyEnum.EUR)
})
it("should set currency from breakfast when no other currency available", () => {
const total: GetRequestedAdditionalPriceParams[0] = {
local: {
price: 100,
currency: CurrencyEnum.SEK,
},
}
const adults = 1
const nights = 1
const breakfast = {
requestedPrice: {
price: 10,
currency: CurrencyEnum.EUR,
},
}
const packages = null
const cheques = 0
const additionalPrice = 0
const additionalPriceCurrency = undefined
getRequestedAdditionalPrice(
total,
adults,
breakfast,
nights,
packages,
cheques,
additionalPrice,
additionalPriceCurrency
)
expect(total.requested?.additionalPriceCurrency).toBe(CurrencyEnum.EUR)
})
it("should not override existing additionalPriceCurrency", () => {
const total: GetRequestedAdditionalPriceParams[0] = {
local: {
price: 100,
currency: CurrencyEnum.SEK,
},
requested: {
currency: CurrencyEnum.CC,
price: 0,
additionalPriceCurrency: CurrencyEnum.NOK,
},
}
const adults = 1
const nights = 1
const breakfast = {
requestedPrice: {
price: 10,
currency: CurrencyEnum.EUR,
},
}
const packages = null
const cheques = 0
const additionalPrice = 0
const additionalPriceCurrency = undefined
getRequestedAdditionalPrice(
total,
adults,
breakfast,
nights,
packages,
cheques,
additionalPrice,
additionalPriceCurrency
)
expect(total.requested?.additionalPriceCurrency).toBe(CurrencyEnum.NOK)
})
it("should handle breakfast without requestedPrice", () => {
const total: GetRequestedAdditionalPriceParams[0] = {
local: {
price: 100,
currency: CurrencyEnum.SEK,
},
}
const adults = 2
const nights = 2
const breakfast = {
requestedPrice: {
price: 0,
currency: CurrencyEnum.SEK,
},
}
const packages = null
const cheques = 0
const additionalPrice = 0
const additionalPriceCurrency = undefined
getRequestedAdditionalPrice(
total,
adults,
breakfast,
nights,
packages,
cheques,
additionalPrice,
additionalPriceCurrency
)
expect(total.requested?.additionalPrice).toBe(0)
})
it("should handle false breakfast value", () => {
const total: GetRequestedAdditionalPriceParams[0] = {
local: {
price: 100,
currency: CurrencyEnum.SEK,
},
}
const adults = 2
const nights = 2
const breakfast = false
const packages = null
const cheques = 0
const additionalPrice = 0
const additionalPriceCurrency = undefined
getRequestedAdditionalPrice(
total,
adults,
breakfast,
nights,
packages,
cheques,
additionalPrice,
additionalPriceCurrency
)
expect(total.requested?.additionalPrice).toBe(0)
})
})
type GetCorporateChequePriceParams = Parameters<typeof getCorporateChequePrice>
describe("getCorporateChequePrice", () => {
it("returns price 0 when rooms are empty", () => {
const nights = 1
const result = getCorporateChequePrice([], nights)
expect(result).toEqual({
local: {
price: 0,
currency: CurrencyEnum.CC,
},
requested: undefined,
})
})
it("returns price for single room with corporate cheque", () => {
const nights = 2
const rooms: GetCorporateChequePriceParams[0] = [
{
adults: 1,
breakfast: false,
roomFeatures: [],
roomRate: {
corporateCheque: {
localPrice: {
numberOfCheques: 3,
additionalPricePerStay: 0,
},
},
},
},
]
const result = getCorporateChequePrice(rooms, nights)
expect(result).toEqual({
local: {
price: 3,
currency: CurrencyEnum.CC,
additionalPrice: 0,
},
requested: undefined,
})
})
it("calculates price with additionalPricePerStay", () => {
const nights = 2
const rooms: GetCorporateChequePriceParams[0] = [
{
adults: 1,
breakfast: false,
roomFeatures: [],
roomRate: {
corporateCheque: {
localPrice: {
numberOfCheques: 2,
additionalPricePerStay: 150,
currency: CurrencyEnum.SEK,
},
},
},
},
]
const result = getCorporateChequePrice(rooms, nights)
expect(result).toEqual({
local: {
price: 2,
currency: CurrencyEnum.CC,
additionalPrice: 150,
additionalPriceCurrency: CurrencyEnum.SEK,
},
requested: undefined,
})
})
it("calculates price with breakfast", () => {
const nights = 2
const rooms: GetCorporateChequePriceParams[0] = [
{
adults: 2,
breakfast: {
localPrice: {
price: 50,
currency: CurrencyEnum.SEK,
},
},
roomFeatures: [],
roomRate: {
corporateCheque: {
localPrice: {
numberOfCheques: 3,
additionalPricePerStay: 100,
currency: CurrencyEnum.SEK,
},
},
},
},
]
const result = getCorporateChequePrice(rooms, nights)
expect(result).toEqual({
local: {
price: 3,
currency: CurrencyEnum.CC,
additionalPrice: 300,
additionalPriceCurrency: CurrencyEnum.SEK,
},
requested: undefined,
})
})
it("calculates price with room features", () => {
const nights = 2
const rooms: GetCorporateChequePriceParams[0] = [
{
adults: 1,
breakfast: false,
roomFeatures: [
{
localPrice: {
totalPrice: 75,
currency: CurrencyEnum.SEK,
},
requestedPrice: {
totalPrice: 10,
currency: CurrencyEnum.EUR,
},
},
],
roomRate: {
corporateCheque: {
localPrice: {
numberOfCheques: 2,
additionalPricePerStay: 50,
currency: CurrencyEnum.SEK,
},
},
},
},
]
const result = getCorporateChequePrice(rooms, nights)
expect(result).toEqual({
local: {
price: 2,
currency: CurrencyEnum.CC,
additionalPrice: 125,
additionalPriceCurrency: CurrencyEnum.SEK,
},
requested: undefined,
})
})
it("calculates requested price when available", () => {
const nights = 2
const rooms: GetCorporateChequePriceParams[0] = [
{
adults: 1,
breakfast: false,
roomFeatures: [],
roomRate: {
corporateCheque: {
localPrice: {
numberOfCheques: 3,
additionalPricePerStay: 100,
currency: CurrencyEnum.SEK,
},
requestedPrice: {
numberOfCheques: 2,
additionalPricePerStay: 15,
currency: CurrencyEnum.EUR,
},
},
},
},
]
const result = getCorporateChequePrice(rooms, nights)
expect(result).toEqual({
local: {
price: 3,
currency: CurrencyEnum.CC,
additionalPrice: 100,
additionalPriceCurrency: CurrencyEnum.SEK,
},
requested: {
price: 2,
currency: CurrencyEnum.CC,
additionalPrice: 15,
additionalPriceCurrency: CurrencyEnum.EUR,
},
})
})
it("calculates requested price with breakfast", () => {
const nights = 2
const rooms: GetCorporateChequePriceParams[0] = [
{
adults: 2,
breakfast: {
localPrice: {
price: 40,
currency: CurrencyEnum.SEK,
},
requestedPrice: {
price: 5,
currency: CurrencyEnum.EUR,
},
},
roomFeatures: [],
roomRate: {
corporateCheque: {
localPrice: {
numberOfCheques: 3,
additionalPricePerStay: 100,
currency: CurrencyEnum.SEK,
},
requestedPrice: {
numberOfCheques: 2,
additionalPricePerStay: 10,
currency: CurrencyEnum.EUR,
},
},
},
},
]
const result = getCorporateChequePrice(rooms, nights)
expect(result).toEqual({
local: {
price: 3,
currency: CurrencyEnum.CC,
additionalPrice: 260,
additionalPriceCurrency: CurrencyEnum.SEK,
},
requested: {
price: 2,
currency: CurrencyEnum.CC,
additionalPrice: 30,
additionalPriceCurrency: CurrencyEnum.EUR,
},
})
})
it("calculates price for multiple rooms", () => {
const nights = 1
const rooms: GetCorporateChequePriceParams[0] = [
{
adults: 1,
breakfast: false,
roomFeatures: [],
roomRate: {
corporateCheque: {
localPrice: {
numberOfCheques: 2,
additionalPricePerStay: 50,
currency: CurrencyEnum.SEK,
},
},
},
},
{
adults: 2,
breakfast: {
localPrice: {
price: 30,
currency: CurrencyEnum.SEK,
},
},
roomFeatures: [],
roomRate: {
corporateCheque: {
localPrice: {
numberOfCheques: 3,
additionalPricePerStay: 75,
currency: CurrencyEnum.SEK,
},
requestedPrice: {
numberOfCheques: 2,
additionalPricePerStay: 10,
currency: CurrencyEnum.EUR,
},
},
},
},
]
const result = getCorporateChequePrice(rooms, nights)
expect(result).toEqual({
local: {
price: 5,
currency: CurrencyEnum.CC,
additionalPrice: 185,
additionalPriceCurrency: CurrencyEnum.SEK,
},
requested: {
price: 2,
currency: CurrencyEnum.CC,
additionalPrice: 10,
additionalPriceCurrency: CurrencyEnum.EUR,
},
})
})
it("does not return price for rooms without corporateCheque", () => {
const nights = 2
const rooms: GetCorporateChequePriceParams[0] = [
{
adults: 1,
breakfast: false,
roomFeatures: [],
roomRate: {
public: {
localPrice: {
pricePerStay: 500,
},
},
},
},
{
adults: 1,
breakfast: false,
roomFeatures: [],
roomRate: {
corporateCheque: {
localPrice: {
numberOfCheques: 3,
additionalPricePerStay: 0,
},
},
},
},
]
const result = getCorporateChequePrice(rooms, nights)
expect(result).toEqual({
local: {
price: 3,
currency: CurrencyEnum.CC,
additionalPrice: 0,
},
requested: undefined,
})
})
it("calculates combined price with breakfast and room features", () => {
const nights = 3
const rooms: GetCorporateChequePriceParams[0] = [
{
adults: 2,
breakfast: {
localPrice: {
price: 25,
currency: CurrencyEnum.SEK,
},
requestedPrice: {
price: 3,
currency: CurrencyEnum.EUR,
},
},
roomFeatures: [
{
localPrice: {
totalPrice: 100,
currency: CurrencyEnum.SEK,
},
requestedPrice: {
totalPrice: 12,
currency: CurrencyEnum.EUR,
},
},
{
localPrice: {
totalPrice: 50,
currency: CurrencyEnum.SEK,
},
requestedPrice: {
totalPrice: 6,
currency: CurrencyEnum.EUR,
},
},
],
roomRate: {
corporateCheque: {
localPrice: {
numberOfCheques: 5,
additionalPricePerStay: 200,
currency: CurrencyEnum.SEK,
},
requestedPrice: {
numberOfCheques: 4,
additionalPricePerStay: 25,
currency: CurrencyEnum.EUR,
},
},
},
},
]
const result = getCorporateChequePrice(rooms, nights)
expect(result).toEqual({
local: {
price: 5,
currency: CurrencyEnum.CC,
additionalPrice: 500,
additionalPriceCurrency: CurrencyEnum.SEK,
},
requested: {
price: 4,
currency: CurrencyEnum.CC,
additionalPrice: 61,
additionalPriceCurrency: CurrencyEnum.EUR,
},
})
})
})
describe("getRedemptionPrice", () => {
it("returns price 0 and default currency when rooms are empty", () => {
const result = getRedemptionPrice([], 1)

View File

@@ -8,12 +8,7 @@ import { calculateRegularPrice } from "../../utils/calculateRegularPrice"
import { sumPackages, sumPackagesRequestedPrice } from "../../utils/SelectRate"
import { detailsStorageName } from "."
import type { BreakfastPackage } from "@scandic-hotels/trpc/routers/hotels/schemas/packages"
import type { Packages } from "@scandic-hotels/trpc/types/packages"
import type {
CorporateChequeProduct,
Product,
} from "@scandic-hotels/trpc/types/roomAvailability"
import type { Product } from "@scandic-hotels/trpc/types/roomAvailability"
import type { User } from "@scandic-hotels/trpc/types/user"
import type { Price } from "../../types/price"
@@ -315,12 +310,20 @@ export function getAdditionalPrice(
}
}
function getRequestedAdditionalPrice(
export function getRequestedAdditionalPrice(
total: Price,
adults: number,
breakfast: BreakfastPackage | false | undefined,
breakfast:
| {
requestedPrice?: { price: number; currency?: CurrencyEnum }
}
| false
| undefined,
nights: number,
packages: Packages | null,
packages:
| { requestedPrice: { totalPrice: number; currency?: CurrencyEnum } }[]
| null
| undefined,
cheques: number,
additionalPrice = 0,
additionalPriceCurrency: CurrencyEnum | null | undefined
@@ -362,14 +365,30 @@ type TRoom = Pick<
"adults" | "breakfast" | "guest" | "roomFeatures" | "roomRate"
>
interface TRoomCorporateCheque extends TRoom {
roomRate: CorporateChequeProduct
type CorporateCheckRoom = PriceCalculationRoom & {
roomRate: {
corporateCheque: {
localPrice: {
numberOfCheques: number
additionalPricePerStay: number
currency?: CurrencyEnum
}
requestedPrice?: {
numberOfCheques: number
additionalPricePerStay: number
currency?: CurrencyEnum
}
}
}
}
function getCorporateChequePrice(rooms: TRoom[], nights: number) {
export function getCorporateChequePrice(
rooms: PriceCalculationRoom[],
nights: number
) {
return rooms
.filter(
(room): room is TRoomCorporateCheque => "corporateCheque" in room.roomRate
(room): room is CorporateCheckRoom => "corporateCheque" in room.roomRate
)
.reduce<Price>(
(total, room) => {