Skip to content

Commit 08fea40

Browse files
committed
[fix] AdPods with resolveAll to false
1 parent d6420de commit 08fea40

File tree

3 files changed

+73
-193
lines changed

3 files changed

+73
-193
lines changed

spec/parser_utils.spec.js

Lines changed: 50 additions & 154 deletions
Original file line numberDiff line numberDiff line change
@@ -1,173 +1,69 @@
11
import { parserUtils } from '../src/parser/parser_utils.js';
22

33
describe('ParserUtils', function () {
4-
describe('splitVAST', function () {
5-
it('should parse normally defined vast pods', () => {
6-
const input = [
7-
{ id: 2, sequence: 1 },
8-
{ id: 3, sequence: 2 },
9-
{ id: 4 },
10-
{ id: 5, sequence: 1 },
11-
{ id: 6, sequence: 2 },
12-
{ id: 7, sequence: 3 },
13-
{ id: 8, sequence: 1 },
14-
{ id: 9, sequence: 2 },
15-
{ id: 10 },
16-
{ id: 11, sequence: 1 },
17-
{ id: 12 },
4+
describe('getSortedAdPods', function () {
5+
it('should return sorted ad pods based on sequence attribute', function () {
6+
const ads = [
7+
{ sequence: '3', id: 'ad3' },
8+
{ sequence: '1', id: 'ad1' },
9+
{ sequence: '2', id: 'ad2' },
1810
];
19-
20-
const expectedOutput = [
21-
[
22-
{ id: 2, sequence: 1 },
23-
{ id: 3, sequence: 2 },
24-
],
25-
[{ id: 4 }],
26-
[
27-
{ id: 5, sequence: 1 },
28-
{ id: 6, sequence: 2 },
29-
{ id: 7, sequence: 3 },
30-
],
31-
[
32-
{ id: 8, sequence: 1 },
33-
{ id: 9, sequence: 2 },
34-
],
35-
[{ id: 10 }],
36-
[{ id: 11, sequence: 1 }],
37-
[{ id: 12 }],
38-
];
39-
40-
const output = parserUtils.splitVAST(input);
41-
42-
expect(output).toEqual(expectedOutput);
11+
const sortedAds = parserUtils.getSortedAdPods(ads);
12+
expect(sortedAds).toEqual([
13+
{ sequence: '1', id: 'ad1' },
14+
{ sequence: '2', id: 'ad2' },
15+
{ sequence: '3', id: 'ad3' },
16+
]);
4317
});
4418

45-
it('should parse vast pods with single sequence', () => {
46-
const input = [
47-
{ id: 1, sequence: 1 },
48-
{ id: 2, sequence: 1 },
49-
{ id: 3, sequence: 1 },
50-
];
51-
52-
const expectedOutput = [
53-
[{ id: 1, sequence: 1 }],
54-
[{ id: 2, sequence: 1 }],
55-
[{ id: 3, sequence: 1 }],
19+
it('should filter out ads without sequence attribute', function () {
20+
const ads = [
21+
{ sequence: '3', id: 'ad3' },
22+
{ id: 'adWithoutSequence' },
23+
{ sequence: '2', id: 'ad2' },
24+
{ sequence: '1', id: 'ad1' },
5625
];
57-
58-
const output = parserUtils.splitVAST(input);
59-
60-
expect(output).toEqual(expectedOutput);
61-
});
62-
63-
it('should parse vast pods with no pods', () => {
64-
const input = [{ id: 1 }, { id: 2 }, { id: 3 }];
65-
66-
const expectedOutput = [[{ id: 1 }], [{ id: 2 }], [{ id: 3 }]];
67-
68-
const output = parserUtils.splitVAST(input);
69-
70-
expect(output).toEqual(expectedOutput);
26+
const sortedAds = parserUtils.getSortedAdPods(ads);
27+
expect(sortedAds).toEqual([
28+
{ sequence: '1', id: 'ad1' },
29+
{ sequence: '2', id: 'ad2' },
30+
{ sequence: '3', id: 'ad3' },
31+
]);
7132
});
7233

73-
it('should parse vast pods with weird sequences', () => {
74-
const input = [
75-
{ id: 1, sequence: 99 },
76-
{ id: 2, sequence: 99 },
77-
{ id: 3, sequence: 99 },
34+
it('should return an empty array if no adPods are provided', function () {
35+
const ads = [
36+
{ id: 'adWithoutSequence1' },
37+
{ id: 'adWithoutSequence2' },
38+
{ id: 'adWithoutSequence3' },
7839
];
79-
80-
const expectedOutput = [[{ id: 1 }], [{ id: 2 }], [{ id: 3 }]];
81-
82-
const output = parserUtils.splitVAST(input);
83-
84-
expect(output).toEqual(expectedOutput);
40+
const sortedAds = parserUtils.getSortedAdPods(ads);
41+
expect(sortedAds).toEqual([]);
8542
});
43+
});
8644

87-
it('should parse vast pods with sequences that not start with index = 1', () => {
88-
const input = [
89-
{ id: 1, sequence: 2 },
90-
{ id: 4 },
91-
{ id: 98, sequence: 3 },
92-
{ id: 99, sequence: 4 },
93-
{ id: 5, sequence: 1 },
94-
{ id: 6, sequence: 2 },
95-
{ id: 7, sequence: 3 },
96-
{ id: 8, sequence: 1 },
97-
{ id: 9, sequence: 2 },
98-
{ id: 10 },
99-
{ id: 11, sequence: 1 },
100-
{ id: 12 },
101-
];
102-
103-
const expectedOutput = [
104-
[{ id: 1 }],
105-
[{ id: 4 }],
106-
[{ id: 98 }],
107-
[{ id: 99 }],
108-
[
109-
{ id: 5, sequence: 1 },
110-
{ id: 6, sequence: 2 },
111-
{ id: 7, sequence: 3 },
112-
],
113-
[
114-
{ id: 8, sequence: 1 },
115-
{ id: 9, sequence: 2 },
116-
],
117-
[{ id: 10 }],
118-
[{ id: 11, sequence: 1 }],
119-
[{ id: 12 }],
45+
describe('getStandAloneAds', function () {
46+
it('should return standalone ads without sequence attribute', function () {
47+
const ads = [
48+
{ sequence: '3', id: 'ad3' },
49+
{ id: 'adWithoutSequence1' },
50+
{ sequence: '1', id: 'ad1' },
51+
{ id: 'adWithoutSequence2' },
12052
];
121-
122-
const output = parserUtils.splitVAST(input);
123-
124-
expect(output).toEqual(expectedOutput);
53+
const standAloneAds = parserUtils.getStandAloneAds(ads);
54+
expect(standAloneAds).toEqual([
55+
{ id: 'adWithoutSequence1' },
56+
{ id: 'adWithoutSequence2' },
57+
]);
12558
});
12659

127-
it('should parse vast pods with sequences that not start with index = 1, and not following incrementally', () => {
128-
const input = [
129-
{ id: 1, sequence: 2 },
130-
{ id: 2, sequence: 4 },
131-
{ id: 4 },
132-
{ id: 98, sequence: 3 },
133-
{ id: 99, sequence: 4 },
134-
{ id: 100, sequence: 17 },
135-
{ id: 101, sequence: 18 },
136-
{ id: 5, sequence: 1 },
137-
{ id: 6, sequence: 2 },
138-
{ id: 7, sequence: 3 },
139-
{ id: 8, sequence: 1 },
140-
{ id: 9, sequence: 2 },
141-
{ id: 10 },
142-
{ id: 11, sequence: 1 },
143-
{ id: 12 },
60+
it('should return an empty array if all ads have sequence attribute', function () {
61+
const ads = [
62+
{ sequence: '1', id: 'ad1' },
63+
{ sequence: '2', id: 'ad2' },
14464
];
145-
146-
const expectedOutput = [
147-
[{ id: 1 }],
148-
[{ id: 2 }],
149-
[{ id: 4 }],
150-
[{ id: 98 }],
151-
[{ id: 99 }],
152-
[{ id: 100 }],
153-
[{ id: 101 }],
154-
[
155-
{ id: 5, sequence: 1 },
156-
{ id: 6, sequence: 2 },
157-
{ id: 7, sequence: 3 },
158-
],
159-
[
160-
{ id: 8, sequence: 1 },
161-
{ id: 9, sequence: 2 },
162-
],
163-
[{ id: 10 }],
164-
[{ id: 11, sequence: 1 }],
165-
[{ id: 12 }],
166-
];
167-
168-
const output = parserUtils.splitVAST(input);
169-
170-
expect(output).toEqual(expectedOutput);
65+
const standAloneAds = parserUtils.getStandAloneAds(ads);
66+
expect(standAloneAds).toEqual([]);
17167
});
17268
});
17369

src/parser/parser_utils.js

Lines changed: 17 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -138,37 +138,23 @@ export function parseDuration(durationString) {
138138
}
139139

140140
/**
141-
* Splits an Array of ads into an Array of Arrays of ads.
142-
* Each subarray contains either one ad or multiple ads (an AdPod)
143-
* @param {Array} ads - An Array of ads to split
144-
* @return {Array}
141+
* Sorts and filters ads that are part of an Ad Pod.
142+
* @param {Array} ads - An array of ad objects.
143+
* @returns {Array} An array of sorted ad objects based on the sequence attribute.
145144
*/
146-
function splitVAST(ads) {
147-
const splittedVAST = [];
148-
let lastAdPod = null;
149-
150-
ads.forEach((ad, i) => {
151-
if (ad.sequence) {
152-
ad.sequence = parseInt(ad.sequence, 10);
153-
}
154-
// The current Ad may be the next Ad of an AdPod
155-
if (ad.sequence > 1) {
156-
const lastAd = ads[i - 1];
157-
// check if the current Ad is exactly the next one in the AdPod
158-
if (lastAd && lastAd.sequence === ad.sequence - 1) {
159-
lastAdPod && lastAdPod.push(ad);
160-
return;
161-
}
162-
// If the ad had a sequence attribute but it was not part of a correctly formed
163-
// AdPod, let's remove the sequence attribute
164-
delete ad.sequence;
165-
}
166-
167-
lastAdPod = [ad];
168-
splittedVAST.push(lastAdPod);
169-
});
145+
function getSortedAdPods(ads = []) {
146+
return ads
147+
.filter((ad) => parseInt(ad.sequence, 10))
148+
.sort((a, b) => a.sequence - b.sequence);
149+
}
170150

171-
return splittedVAST;
151+
/**
152+
* Filters out AdPods of given ads array and returns only standalone ads without sequence attribute.
153+
* @param {Array} ads - An array of ad objects.
154+
* @returns {Array} An array of standalone ad.
155+
*/
156+
function getStandAloneAds(ads = []) {
157+
return ads.filter((ad) => !parseInt(ad.sequence, 10));
172158
}
173159

174160
/**
@@ -343,7 +329,8 @@ export const parserUtils = {
343329
copyNodeAttribute,
344330
parseAttributes,
345331
parseDuration,
346-
splitVAST,
332+
getStandAloneAds,
333+
getSortedAdPods,
347334
assignAttributes,
348335
mergeWrapperAdData,
349336
};

src/parser/vast_parser.js

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -96,10 +96,7 @@ export class VASTParser extends EventEmitter {
9696
new Error('No more ads are available for the given VAST')
9797
);
9898
}
99-
100-
const ads = all
101-
? util.flatten(this.remainingAds)
102-
: this.remainingAds.shift();
99+
const ads = all ? this.remainingAds : [this.remainingAds.shift()];
103100
this.errorURLTemplates = [];
104101

105102
return this.resolveAds(ads, {
@@ -303,12 +300,12 @@ export class VASTParser extends EventEmitter {
303300
) {
304301
ads[0].sequence = wrapperSequence;
305302
}
306-
307-
// Split the VAST in case we don't want to resolve everything at the first time
308303
if (resolveAll === false) {
309-
this.remainingAds = parserUtils.splitVAST(ads);
310-
// Remove the first element from the remaining ads array, since we're going to resolve that element
311-
ads = this.remainingAds.shift();
304+
const adPods = parserUtils.getSortedAdPods(ads);
305+
const standAloneAds = parserUtils.getStandAloneAds(ads);
306+
// Resolve only AdPod found first, if no AdPod found resolve only the first stand alone Ad
307+
ads = adPods.length ? adPods : [standAloneAds.shift()];
308+
this.remainingAds = standAloneAds;
312309
}
313310

314311
return this.resolveAds(ads, {

0 commit comments

Comments
 (0)