Skip to content

Commit 005ef71

Browse files
authored
Merge pull request #1033 from duffelhq/helper-functions
Exposes `hasService` helper
2 parents f0a2c7f + 9cfa669 commit 005ef71

File tree

5 files changed

+172
-0
lines changed

5 files changed

+172
-0
lines changed
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
import { SeatMap } from 'types'
2+
import { hasAvailableSeatService } from './hasAvailableSeatService'
3+
4+
describe('hasAvailableSeatService', () => {
5+
it('should return false when seatMaps is undefined', () => {
6+
expect(hasAvailableSeatService()).toBe(false)
7+
})
8+
9+
it('should return false when seatMaps is an empty array', () => {
10+
expect(hasAvailableSeatService([])).toBe(false)
11+
})
12+
13+
it('should return false when seatMaps do not contain any seat with available services', () => {
14+
const seatMaps: SeatMap[] = [
15+
{
16+
cabins: [
17+
{
18+
rows: [
19+
{
20+
sections: [
21+
{
22+
elements: [
23+
{
24+
type: 'seat',
25+
available_services: [],
26+
},
27+
],
28+
},
29+
],
30+
},
31+
],
32+
},
33+
],
34+
} as any,
35+
]
36+
const result = hasAvailableSeatService(seatMaps)
37+
expect(result).toBe(false)
38+
})
39+
40+
it('should return true when seatMaps contain a seat with available services', () => {
41+
const seatMaps: SeatMap[] = [
42+
{
43+
cabins: [
44+
{
45+
rows: [
46+
{
47+
sections: [
48+
{
49+
elements: [
50+
{
51+
type: 'seat',
52+
available_services: ['service1', 'service2'],
53+
},
54+
],
55+
},
56+
],
57+
},
58+
],
59+
},
60+
],
61+
} as any,
62+
]
63+
const result = hasAvailableSeatService(seatMaps)
64+
expect(result).toBe(true)
65+
})
66+
})
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import { SeatMap } from 'types'
2+
3+
export function hasAvailableSeatService(seatMaps?: SeatMap[]): boolean {
4+
if (!Array.isArray(seatMaps) || seatMaps.length === 0) return false
5+
6+
for (const seatMap of seatMaps) {
7+
for (const cabin of seatMap.cabins) {
8+
for (const rows of cabin.rows) {
9+
for (const section of rows.sections) {
10+
for (const element of section.elements) {
11+
if (
12+
element.type === 'seat' &&
13+
element.available_services.length > 0
14+
) {
15+
return true
16+
}
17+
}
18+
}
19+
}
20+
}
21+
}
22+
23+
return false
24+
}

src/functions/hasService.spec.ts

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
import { SeatMap } from 'types'
2+
import { hasService } from './hasService'
3+
4+
describe('hasService', () => {
5+
// A basic offer with no available services
6+
const baseOffer = {
7+
available_services: [],
8+
} as any
9+
10+
it('should return false when no seat maps passed and no available services on offer (no services available at all)', () => {
11+
// No seat maps provided and the offer has no available services
12+
expect(hasService(baseOffer)).toBe(false)
13+
})
14+
15+
it('should return false when seat maps is an empty array and no available services on offer', () => {
16+
// Seat maps provided as empty array and no service on the offer
17+
expect(hasService(baseOffer, [])).toBe(false)
18+
})
19+
20+
it('should return true when no seat maps passed but offer has a service available', () => {
21+
// Offer has a service (e.g. a baggage service) with maximum_quantity > 0
22+
// and seat maps are not provided
23+
24+
const offerWithService = {
25+
available_services: [{ maximum_quantity: 1, type: 'baggage' }],
26+
} as any
27+
28+
expect(hasService(offerWithService)).toBe(true)
29+
})
30+
31+
it('should return true when only seats available in seat maps', () => {
32+
// Offer has no available services, but seat maps include a seat with available services
33+
const seatMaps: SeatMap[] = [
34+
{
35+
cabins: [
36+
{
37+
rows: [
38+
{
39+
sections: [
40+
{
41+
elements: [
42+
{
43+
type: 'seat',
44+
available_services: ['service1', 'service2'],
45+
},
46+
],
47+
},
48+
],
49+
},
50+
],
51+
},
52+
],
53+
},
54+
] as any
55+
56+
expect(hasService(baseOffer, seatMaps)).toBe(true)
57+
})
58+
it('should return true when only baggages available in offer', () => {
59+
// Offer has an available baggage service and seat maps are empty
60+
const offerWithBaggage = {
61+
available_services: [{ maximum_quantity: 1, type: 'baggage' }],
62+
} as any
63+
64+
expect(hasService(offerWithBaggage, [])).toBe(true)
65+
expect(hasService(offerWithBaggage, undefined)).toBe(true)
66+
})
67+
})

src/functions/hasService.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import { Offer, SeatMap } from 'types'
2+
import { hasAvailableSeatService } from './hasAvailableSeatService'
3+
4+
export function hasService(offer: Offer, seatMaps?: SeatMap[]) {
5+
const offerHasService =
6+
offer &&
7+
Array.isArray(offer.available_services) &&
8+
offer.available_services.some((service) => service.maximum_quantity > 0)
9+
10+
return offerHasService || hasAvailableSeatService(seatMaps)
11+
}

src/index.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,3 +102,7 @@ export class Duffel {
102102
}
103103

104104
export const DuffelError = _DuffelError
105+
106+
// Exports helper functions:
107+
export * from './functions/hasService'
108+
export * from './functions/hasAvailableSeatService'

0 commit comments

Comments
 (0)