• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

DaniSomoza / galactic-commander / 12728621970

11 Jan 2025 11:55PM UTC coverage: 47.963% (-4.1%) from 52.086%
12728621970

Pull #12

github

web-flow
Merge e784abf9e into a8e301a23
Pull Request #12: [fleets] Explore planets

214 of 913 branches covered (23.44%)

Branch coverage included in aggregate %.

154 of 505 new or added lines in 55 files covered. (30.5%)

10 existing lines in 9 files now uncovered.

1564 of 2794 relevant lines covered (55.98%)

3.46 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

15.91
/packages/game-api-microservice/src/services/buildUnitsService.ts
1
import playerRepository from 'game-engine/dist/repositories/playerRepository'
2✔
2
import taskRepository from 'game-engine/dist/repositories/taskRepository'
2✔
3
import universeRepository from 'game-engine/dist/repositories/universeRepository'
2✔
4
import planetRepository from 'game-engine/dist/repositories/planetRepository'
2✔
5
import fleetRepository from 'game-engine/dist/repositories/fleetRepository'
2✔
6
import playerUnitsRepository from 'game-engine/dist/repositories/playerUnitsRepository'
2✔
7
import createStartBuildUnitsTask from 'game-engine/dist/engine/tasks/utils/createStartBuildUnitsTask'
2✔
8
import NotFoundError from 'auth-microservice/dist/errors/NotFoundError'
2✔
9
import BadRequestError from 'auth-microservice/dist/errors/BadRequestError'
2✔
10
import ConflictError from 'auth-microservice/dist/errors/ConflictError'
2✔
11

12
import cleanPlayerFields from '../utils/cleanPlayerFields'
2✔
13
import { startResearchResponseType, updateResearchQueueResponseType } from '../types/Research'
14
import cleanTaskFields from '../utils/cleanTaskFields'
2✔
15
import { UnitTypes } from '../types/Unit'
16
import { PlanetCoordinatesType } from '../types/Planet'
17

18
type BuildUnitsData = {
19
  username: string
20
  unitName: string
21
  amount: number
22
  universeName: string
23
  executeTaskAt?: number
24
  planetCoordinates: PlanetCoordinatesType
25
}
26

27
async function startBuildUnits({
28
  username,
29
  unitName,
30
  amount,
31
  universeName,
32
  planetCoordinates,
33
  executeTaskAt
34
}: BuildUnitsData): Promise<startResearchResponseType> {
35
  const universe = await universeRepository.findUniverseByName(universeName)
×
36

37
  if (!universe) {
×
38
    throw new NotFoundError('invalid universe', { universeName })
×
39
  }
40

41
  const universeId = universe._id.toString()
×
42

43
  const player = await playerRepository.findPlayerByUsername(username, universeId)
×
44

45
  if (!player) {
×
46
    throw new NotFoundError('invalid player', { username, universeName })
×
47
  }
48

49
  const planet = await planetRepository.findPlanetByCoordinates(planetCoordinates)
×
50

51
  if (!planet) {
×
52
    throw new NotFoundError('invalid planet', {
×
53
      username,
54
      planetCoordinates
55
    })
56
  }
57

58
  const isValidPlanetOwner = planet.ownerId === player._id.toString()
×
59

60
  if (!isValidPlanetOwner) {
×
61
    throw new ConflictError('invalid planet owner', {
×
62
      username,
63
      planetCoordinates
64
    })
65
  }
66

67
  const raceUnit = player.race.units.find((unit) => unit.name === unitName)
×
68
  const planetUnit = planet.units.find((unit) => unit.name === unitName)
×
69

70
  const unit = raceUnit || planetUnit
×
71

72
  if (!unit) {
×
73
    throw new NotFoundError('invalid unit', { unitName })
×
74
  }
75

76
  if (executeTaskAt && executeTaskAt < new Date().getTime()) {
×
77
    throw new BadRequestError('invalid schedule', { executeTaskAt })
×
78
  }
79

80
  // TODO: checkActiveBuild ??? if executeTaskAt is not defined
81

82
  const startBuildUnitTask = createStartBuildUnitsTask(
×
83
    universeId,
84
    player._id.toString(),
85
    planet._id.toString(),
86
    unit._id.toString(),
87
    amount,
88
    executeTaskAt
89
  )
90

91
  const newTask = await taskRepository.createStartBuildUnitsTask(startBuildUnitTask)
×
92

93
  return { task: cleanTaskFields(newTask) }
×
94
}
95

96
type UpdateBuildUnitsQueueData = {
97
  username: string
98
  universeName: string
99
  unitType: UnitTypes
100
  buildUnitsQueue: {
101
    unitName: string
102
    amount: number
103
  }[]
104
  planetCoordinates: PlanetCoordinatesType
105
}
106

107
async function updateBuildUnitsQueue({
108
  username,
109
  universeName,
110
  unitType,
111
  buildUnitsQueue,
112
  planetCoordinates
113
}: UpdateBuildUnitsQueueData): Promise<updateResearchQueueResponseType> {
114
  const universe = await universeRepository.findUniverseByName(universeName)
×
115

116
  if (!universe) {
×
117
    throw new NotFoundError('invalid universe', { universeName })
×
118
  }
119

120
  const universeId = universe._id.toString()
×
121

122
  const player = await playerRepository.findPlayerByUsername(username, universeId)
×
123

124
  if (!player) {
×
125
    throw new NotFoundError('invalid player', { username, universeName })
×
126
  }
127

128
  const planet = await planetRepository.findPlanetByCoordinates(planetCoordinates)
×
129

130
  if (!planet) {
×
131
    throw new NotFoundError('invalid planet', {
×
132
      username,
133
      planetCoordinates
134
    })
135
  }
136

137
  const isValidPlanetOwner = planet.ownerId === player._id.toString()
×
138

139
  if (!isValidPlanetOwner) {
×
140
    throw new ConflictError('invalid planet owner', {
×
141
      username,
142
      planetCoordinates
143
    })
144
  }
145

146
  const isValidQueue = buildUnitsQueue.every(({ unitName }) => {
×
147
    const raceUnit = player.race.units.find((unit) => unit.name === unitName)
×
148
    const planetUnit = planet.units.find((unit) => unit.name === unitName)
×
149

150
    const unit = raceUnit || planetUnit
×
151

152
    return !!unit && unitType === unit.type
×
153
  })
154

155
  if (!isValidQueue) {
×
156
    throw new NotFoundError('invalid build units queue', { buildUnitsQueue })
×
157
  }
158

159
  // update planet build units queue
160
  const path: Record<UnitTypes, 'troops' | 'spaceships' | 'defenses'> = {
×
161
    TROOP: 'troops',
162
    SPACESHIP: 'spaceships',
163
    DEFENSE: 'defenses'
164
  }
165

166
  planet.unitBuild[path[unitType]].queue = buildUnitsQueue
×
167

168
  if (!planet.unitBuild[path[unitType]].activeBuild) {
×
169
    // if no build is active, just start building the first unit in the queue
170
    const nextBuildUnits = planet.unitBuild[path[unitType]].queue.shift()
×
171
    if (nextBuildUnits) {
×
172
      await startBuildUnits({
×
173
        username,
174
        unitName: nextBuildUnits.unitName,
175
        amount: nextBuildUnits.amount,
176
        planetCoordinates,
177
        universeName
178
      })
179
    }
180
  }
181

182
  await planet.save()
×
183

NEW
184
  const fleets = await fleetRepository.findFleetsByPlayerId(player._id.toString())
×
NEW
185
  const playerUnits = await playerUnitsRepository.findPlayerUnits(player._id.toString())
×
186

NEW
187
  return { player: cleanPlayerFields(player, fleets, playerUnits) }
×
188
}
189

190
const buildUnitsService = {
2✔
191
  startBuildUnits,
192
  updateBuildUnitsQueue
193
}
194

195
export default buildUnitsService
2✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc