UNPKG

@jeremyckahn/farmhand

Version:
372 lines (338 loc) • 10.9 kB
import { testState } from '../../test-utils/index.js' import { LOAN_PAYOFF } from '../../templates.js' import { carrot, carrotSeed, corn } from '../../data/crops/index.js' import { apple, bronzeOre, coal, milk1, saltRock } from '../../data/items.js' import { carrotSoup } from '../../data/recipes.js' import { sellItem } from './sellItem.js' describe('sellItem', () => { test('sells item', () => { const state = sellItem( testState({ // Chosen so carrot's SPRING high-demand seasonal bonus doesn't apply. dayCount: 16, inventory: [{ id: carrot.id, quantity: 1 }], itemsSold: {}, loanBalance: 0, money: 100, pendingPeerMessages: [], todaysNotifications: [], revenue: 0, todaysRevenue: 0, valueAdjustments: { [carrotSeed.id]: 1 }, }), carrot ) expect(state.inventory).toEqual([]) expect(state.money).toEqual(125) expect(state.revenue).toEqual(25) expect(state.todaysRevenue).toEqual(25) expect(state.itemsSold).toEqual({ carrot: 1 }) }) test('does not change revenue for seed sales', () => { const state = sellItem( testState({ inventory: [{ id: carrotSeed.id, quantity: 1 }], itemsSold: {}, loanBalance: 0, money: 100, pendingPeerMessages: [], todaysNotifications: [], revenue: 0, todaysRevenue: 0, valueAdjustments: { [carrotSeed.id]: 1 }, }), carrotSeed ) expect(state.inventory).toEqual([]) expect(state.money).toEqual(107.5) expect(state.revenue).toEqual(0) expect(state.todaysRevenue).toEqual(0) expect(state.itemsSold).toEqual({ [carrotSeed.id]: 1 }) }) test('applies achievement bonus to farm products', () => { const state = sellItem( testState({ // Chosen so carrot's SPRING high-demand seasonal bonus doesn't apply. dayCount: 16, inventory: [{ id: carrot.id, quantity: 1 }], itemsSold: {}, loanBalance: 0, money: 100, pendingPeerMessages: [], todaysNotifications: [], revenue: 0, todaysRevenue: 0, valueAdjustments: { [carrot.id]: 1 }, completedAchievements: { 'i-am-rich-3': true, }, }), carrot ) expect(state.inventory).toEqual([]) expect(state.money).toEqual(131.25) expect(state.revenue).toEqual(31.25) expect(state.todaysRevenue).toEqual(31.25) expect(state.itemsSold).toEqual({ [carrot.id]: 1 }) }) test('does not apply achievement bonus to seeds', () => { const state = sellItem( testState({ inventory: [{ id: carrotSeed.id, quantity: 1 }], itemsSold: {}, loanBalance: 0, money: 100, pendingPeerMessages: [], todaysNotifications: [], revenue: 0, todaysRevenue: 0, valueAdjustments: { [carrotSeed.id]: 1 }, completedAchievements: { 'i-am-rich-3': true, }, }), carrotSeed ) expect(state.inventory).toEqual([]) expect(state.money).toEqual(107.5) expect(state.revenue).toEqual(0) expect(state.todaysRevenue).toEqual(0) expect(state.itemsSold).toEqual({ [carrotSeed.id]: 1 }) }) test('updates learnedRecipes', () => { const { learnedRecipes } = sellItem( testState({ // Chosen so carrot's SPRING high-demand seasonal bonus doesn't apply. dayCount: 16, inventory: [{ id: carrot.id, quantity: 2 }], itemsSold: {}, loanBalance: 0, money: 100, pendingPeerMessages: [], todaysNotifications: [], revenue: 0, todaysRevenue: 0, valueAdjustments: { [carrot.id]: 1 }, }), carrot, 15 ) expect(learnedRecipes[carrotSoup.id]).toBeTruthy() }) describe('there is an outstanding loan', () => { let state: farmhand.state describe('item is not a farm product', () => { beforeEach(() => { state = sellItem( testState({ experience: 0, inventory: [{ id: carrotSeed.id, quantity: 3 }], itemsSold: {}, loanBalance: 100, money: 100, pendingPeerMessages: [], todaysNotifications: [], revenue: 0, todaysRevenue: 0, valueAdjustments: { [carrotSeed.id]: 1 }, }), carrotSeed, 3 ) }) test('sale is not garnished', () => { expect(state.loanBalance).toEqual(100) expect(state.money).toEqual(122.5) expect(state.revenue).toEqual(0) expect(state.todaysRevenue).toEqual(0) }) test('experience is not gained', () => { expect(state.experience).toEqual(0) }) }) describe('item is a farm product', () => { describe('loan is greater than garnishment', () => { test('sale is garnished', () => { state = sellItem( testState({ // Chosen so carrot's SPRING high-demand seasonal bonus doesn't apply. dayCount: 16, inventory: [{ id: carrot.id, quantity: 3 }], itemsSold: {}, loanBalance: 100, money: 100, pendingPeerMessages: [], todaysNotifications: [], revenue: 0, todaysRevenue: 0, valueAdjustments: { [carrot.id]: 1 }, }), carrot, 3 ) expect(state.loanBalance).toEqual(96.25) expect(state.money).toEqual(171.25) expect(state.revenue).toEqual(71.25) expect(state.todaysRevenue).toEqual(71.25) }) }) describe('loan is less than garnishment', () => { beforeEach(() => { state = sellItem( testState({ // Chosen so carrot's SPRING high-demand seasonal bonus doesn't apply. dayCount: 16, experience: 0, inventory: [{ id: carrot.id, quantity: 3 }], itemsSold: {}, loanBalance: 1.5, money: 100, pendingPeerMessages: [], todaysNotifications: [], revenue: 0, todaysRevenue: 0, valueAdjustments: { [carrot.id]: 1 }, }), carrot, 3 ) }) test('loan is payed off', () => { expect(state.loanBalance).toEqual(0) }) test('sale is reduced based on remaining loan balance', () => { expect(state.money).toEqual(173.5) expect(state.todaysRevenue).toEqual(73.5) }) test('payoff notification is shown', () => { expect(state.todaysNotifications).toEqual([ { message: LOAN_PAYOFF(), severity: 'success' }, ]) }) test('experience is gained', () => { expect(state.experience).toEqual(3) }) }) }) }) const experienceTestArgs = [ carrot, apple, milk1, coal, carrotSoup, bronzeOre, saltRock, ].map(item => [item.type, item]) test.each(experienceTestArgs)( 'selling item of type %s gives experience', (_, item) => { // Cast item to ensure TypeScript recognizes it as an item object const itemObj = item as any const state = sellItem( testState({ experience: 0, inventory: [{ id: itemObj.id, quantity: 1 }], itemsSold: {}, loanBalance: 0, money: 100, pendingPeerMessages: [], todaysNotifications: [], revenue: 0, todaysRevenue: 0, valueAdjustments: { [itemObj.id]: 1 }, }), itemObj, 1 ) expect(state.experience).toEqual(1) } ) describe('seasonal demand', () => { test('applies a high demand bonus during a crop high demand season', () => { // dayCount 1 is SPRING, carrot's configured high demand season. const state = sellItem( testState({ dayCount: 1, inventory: [{ id: carrot.id, quantity: 1 }], itemsSold: {}, loanBalance: 0, money: 100, pendingPeerMessages: [], todaysNotifications: [], revenue: 0, todaysRevenue: 0, valueAdjustments: { [carrot.id]: 1 }, }), carrot ) expect(state.money).toEqual(130) expect(state.revenue).toEqual(30) }) test('bases loan garnishment on the seasonally-adjusted sale price, not the base price', () => { // dayCount 1 is SPRING, carrot's configured high demand season, so the // $25 base value sells for $30. Garnishment is 5% of that $30 (= // $1.50), not 5% of the un-boosted $25 (= $1.25) - otherwise the // effective garnishment rate would drift with the season instead of // staying at a flat LOAN_GARNISHMENT_RATE. const state = sellItem( testState({ dayCount: 1, inventory: [{ id: carrot.id, quantity: 1 }], itemsSold: {}, loanBalance: 100, money: 100, pendingPeerMessages: [], todaysNotifications: [], revenue: 0, todaysRevenue: 0, valueAdjustments: { [carrot.id]: 1 }, }), carrot ) expect(state.loanBalance).toEqual(98.5) expect(state.money).toEqual(128.5) expect(state.revenue).toEqual(28.5) }) test('applies a low demand penalty during a crop low demand season', () => { // dayCount 1 is SPRING, corn's configured low demand season. const state = sellItem( testState({ dayCount: 1, inventory: [{ id: corn.id, quantity: 1 }], itemsSold: {}, loanBalance: 0, money: 100, pendingPeerMessages: [], todaysNotifications: [], revenue: 0, todaysRevenue: 0, valueAdjustments: { [corn.id]: 1 }, }), corn ) expect(state.money).toEqual(156) expect(state.revenue).toEqual(56) }) test('does not apply the seasonal multiplier to seed sales', () => { // dayCount 1 is SPRING, which is carrot's high demand season, but this // must not apply to selling the seed - see the #140 guard in Item.tsx. const state = sellItem( testState({ dayCount: 1, inventory: [{ id: carrotSeed.id, quantity: 1 }], itemsSold: {}, loanBalance: 0, money: 100, pendingPeerMessages: [], todaysNotifications: [], revenue: 0, todaysRevenue: 0, valueAdjustments: { [carrotSeed.id]: 1 }, }), carrotSeed ) expect(state.money).toEqual(107.5) }) }) })