sr-npm 2.0.17 → 2.0.19

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,290 @@
1
+ class MockJobBuilder {
2
+ constructor() {
3
+ this.reset();
4
+ }
5
+
6
+ reset() {
7
+ this.jobData = {
8
+ id: this.generateId(),
9
+ title: "Software Engineer",
10
+ uuid: this.generateUuid(),
11
+ refNumber: this.generateRefNumber(),
12
+ company: {
13
+ identifier: "TheWarehouseGroup1",
14
+ name: "The Warehouse Group"
15
+ },
16
+ location: {
17
+ city: "Auckland",
18
+ region: "Auckland Region",
19
+ country: "nz",
20
+ address: "123 Queen Street",
21
+ postalCode: "1010",
22
+ remote: false,
23
+ latitude: "-36.8484597",
24
+ longitude: "174.7633315",
25
+ fullLocation: "Auckland, Auckland Region, New Zealand"
26
+ },
27
+ employmentType: "Full-time",
28
+ customField: [
29
+ {
30
+ fieldId: "5cd160b26b2f07000673dc00",
31
+ fieldLabel: "Brands",
32
+ valueId: "2b6526b2-ed37-426c-8592-1c580f462334",
33
+ valueLabel: "The Warehouse"
34
+ }
35
+ ]
36
+ };
37
+ return this;
38
+ }
39
+
40
+ generateId() {
41
+ return `74400009${Math.floor(1000000 + Math.random() * 9000000)}`;
42
+ }
43
+
44
+ generateUuid() {
45
+ return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (c) => {
46
+ const r = Math.random() * 16 | 0;
47
+ const v = c === 'x' ? r : (r & 0x3 | 0x8);
48
+ return v.toString(16);
49
+ });
50
+ }
51
+
52
+ generateRefNumber() {
53
+ return `REF${Math.floor(10000 + Math.random() * 90000)}G`;
54
+ }
55
+
56
+ withId(id) {
57
+ this.jobData.id = id;
58
+ return this;
59
+ }
60
+
61
+ withTitle(title) {
62
+ this.jobData.title = title;
63
+ return this;
64
+ }
65
+
66
+ withUuid(uuid) {
67
+ this.jobData.uuid = uuid;
68
+ return this;
69
+ }
70
+
71
+ withRefNumber(refNumber) {
72
+ this.jobData.refNumber = refNumber;
73
+ return this;
74
+ }
75
+
76
+ withCompany(identifier, name) {
77
+ this.jobData.company = {
78
+ identifier: identifier || this.jobData.company.identifier,
79
+ name: name || this.jobData.company.name
80
+ };
81
+ return this;
82
+ }
83
+
84
+ withLocation(locationData) {
85
+ this.jobData.location = {
86
+ ...this.jobData.location,
87
+ ...locationData
88
+ };
89
+ return this;
90
+ }
91
+
92
+ withCity(city, region = null, fullLocation = null) {
93
+ this.jobData.location.city = city;
94
+ if (region) this.jobData.location.region = region;
95
+ if (fullLocation) {
96
+ this.jobData.location.fullLocation = fullLocation;
97
+ } else {
98
+ this.jobData.location.fullLocation = `${city}, ${this.jobData.location.region}, New Zealand`;
99
+ }
100
+ return this;
101
+ }
102
+
103
+ withEmploymentType(employmentType) {
104
+ this.jobData.employmentType = employmentType;
105
+ return this;
106
+ }
107
+
108
+ withCustomField(fieldId, fieldLabel, valueId, valueLabel) {
109
+ this.jobData.customField.push({
110
+ fieldId,
111
+ fieldLabel,
112
+ valueId,
113
+ valueLabel
114
+ });
115
+ return this;
116
+ }
117
+
118
+ withCustomFields(fields) {
119
+ this.jobData.customField = fields;
120
+ return this;
121
+ }
122
+
123
+ withMultiRefCustomValues(categoryIds) {
124
+ this.jobData.multiRefJobsCustomValues = categoryIds;
125
+ return this;
126
+ }
127
+
128
+ withCategory(categoryId) {
129
+ if (!this.jobData.multiRefJobsCustomValues) {
130
+ this.jobData.multiRefJobsCustomValues = [];
131
+ }
132
+ this.jobData.multiRefJobsCustomValues.push(categoryId);
133
+ return this;
134
+ }
135
+
136
+ withDepartment(department) {
137
+ this.jobData.department = department;
138
+ return this;
139
+ }
140
+
141
+ withJobDescription(companyDesc, jobDesc, qualifications, additionalInfo = null) {
142
+ this.jobData.jobDescription = {
143
+ companyDescription: { text: companyDesc },
144
+ jobDescription: { text: jobDesc },
145
+ qualifications: { text: qualifications }
146
+ };
147
+ if (additionalInfo) {
148
+ this.jobData.jobDescription.additionalInformation = { text: additionalInfo };
149
+ }
150
+ return this;
151
+ }
152
+
153
+ withApplyLink(link) {
154
+ this.jobData.applyLink = link;
155
+ return this;
156
+ }
157
+
158
+ withLinkJobsTitle(link) {
159
+ this.jobData['link-jobs-title'] = link;
160
+ return this;
161
+ }
162
+
163
+ forPositionPage() {
164
+ if (!this.jobData._id) {
165
+ this.jobData._id = this.generateId();
166
+ }
167
+ if (!this.jobData.department) {
168
+ this.jobData.department = 'Technology';
169
+ }
170
+ if (!this.jobData.jobDescription) {
171
+ this.withJobDescription(
172
+ '<p>Great company to work for</p>',
173
+ '<p>You will build awesome stuff</p>',
174
+ '<p>Must know how to code</p>',
175
+ '<p>Additional info here</p>'
176
+ );
177
+ }
178
+ if (!this.jobData.applyLink) {
179
+ this.jobData.applyLink = `https://apply.com/${this.jobData.id}`;
180
+ }
181
+ return this;
182
+ }
183
+
184
+ asRemote() {
185
+ this.jobData.location.remote = true;
186
+ return this;
187
+ }
188
+
189
+ asOnsite() {
190
+ this.jobData.location.remote = false;
191
+ return this;
192
+ }
193
+
194
+ build() {
195
+ const result = { ...this.jobData };
196
+ this.reset();
197
+ return result;
198
+ }
199
+
200
+ static createDefault() {
201
+ return new MockJobBuilder().build();
202
+ }
203
+
204
+ static createSeniorEngineer() {
205
+ return new MockJobBuilder()
206
+ .withTitle("Senior Software Engineer")
207
+ .withCity("Dunedin", "Otago Region")
208
+ .withEmploymentType("Full-time")
209
+ .build();
210
+ }
211
+
212
+ static createBackendDeveloper() {
213
+ return new MockJobBuilder()
214
+ .withTitle("Backend Developer")
215
+ .withCity("Auckland", "Auckland Region")
216
+ .withEmploymentType("Part-time")
217
+ .build();
218
+ }
219
+
220
+ static createProductManager() {
221
+ return new MockJobBuilder()
222
+ .withTitle("Product Manager")
223
+ .withCity("Wellington", "Wellington Region")
224
+ .withEmploymentType("Full-time")
225
+ .asRemote()
226
+ .build();
227
+ }
228
+
229
+ static createMultiple(count, customizer = null) {
230
+ const jobs = [];
231
+ for (let i = 0; i < count; i++) {
232
+ const builder = new MockJobBuilder();
233
+ if (customizer) {
234
+ customizer(builder, i);
235
+ }
236
+ jobs.push(builder.build());
237
+ }
238
+ return jobs;
239
+ }
240
+
241
+ static createJobsWithSameField(fieldId, count = 3,options = {}) {
242
+ const {
243
+ titlePrefix = null,
244
+ randomTitles = true
245
+ } = options;
246
+
247
+ const jobs = [];
248
+ const titles = [
249
+ 'Frontend Developer', 'Backend Developer', 'Full Stack Engineer',
250
+ 'DevOps Engineer', 'QA Engineer', 'Data Scientist',
251
+ 'Product Manager', 'UX Designer', 'System Architect'
252
+ ];
253
+ const cities = [
254
+ { city: 'Auckland', region: 'Auckland Region' },
255
+ { city: 'Wellington', region: 'Wellington Region' },
256
+ { city: 'Christchurch', region: 'Canterbury Region' },
257
+ { city: 'Hamilton', region: 'Waikato Region' },
258
+ { city: 'Dunedin', region: 'Otago Region' }
259
+ ];
260
+
261
+ for (let i = 0; i < count; i++) {
262
+ let jobTitle;
263
+ if (titlePrefix) {
264
+ jobTitle = `${titlePrefix} ${i + 1}`;
265
+ } else if (randomTitles) {
266
+ const randomTitle = titles[Math.floor(Math.random() * titles.length)];
267
+ jobTitle = `${randomTitle} ${i + 1}`;
268
+ } else {
269
+ jobTitle = `Job ${i + 1}`;
270
+ }
271
+
272
+ const randomCity = cities[Math.floor(Math.random() * cities.length)];
273
+
274
+ const job = new MockJobBuilder()
275
+ .withTitle(jobTitle)
276
+ .withCity(randomCity.city, randomCity.region)
277
+ .withMultiRefCustomValues([{ _id: fieldId }])
278
+ .withLinkJobsTitle(`/jobs/${jobTitle.toLowerCase().replace(/\s+/g, '-')}`)
279
+ .forPositionPage()
280
+ .build();
281
+
282
+ job._id = `job-${jobTitle.toLowerCase().replace(/\s+/g, '-')}`;
283
+ jobs.push(job);
284
+ }
285
+ return jobs;
286
+ }
287
+ }
288
+
289
+ module.exports = MockJobBuilder;
290
+
@@ -0,0 +1,371 @@
1
+ const rewire = require('rewire');
2
+ const MockJobBuilder = require('./mockJobBuilder');
3
+ const { CAREERS_MULTI_BOXES_PAGE_CONSTS, CATEGORY_CUSTOM_FIELD_ID_IN_CMS } = require('../backend/careersMultiBoxesPageIds');
4
+
5
+ // Load modules with rewire
6
+ const careersMultiBoxesPage = rewire('../pages/careersMultiBoxesPage');
7
+ const pagesUtils = rewire('../pages/pagesUtils');
8
+
9
+ const secondarySearch = careersMultiBoxesPage.__get__('secondarySearch');
10
+ const primarySearch = pagesUtils.__get__('primarySearch');
11
+ const loadCategoriesListPrimarySearch = pagesUtils.__get__('loadCategoriesListPrimarySearch');
12
+
13
+
14
+ describe('secondarySearch function tests', () => {
15
+ let mockW;
16
+ let mockJobsRepeater;
17
+ let mockPaginationCurrentText;
18
+ let mockPaginationTotalCountText;
19
+ let mockPageButtonNext;
20
+ let mockPageButtonPrevious;
21
+ let mockTotalJobsCountText;
22
+ let mockJobsMultiStateBox;
23
+
24
+ beforeEach(() => {
25
+ mockJobsRepeater = { data: null };
26
+ mockPaginationCurrentText = { text: '' };
27
+ mockPaginationTotalCountText = { text: '' };
28
+ mockPageButtonNext = {
29
+ enable: jest.fn(),
30
+ disable: jest.fn()
31
+ };
32
+ mockPageButtonPrevious = {
33
+ enable: jest.fn(),
34
+ disable: jest.fn()
35
+ };
36
+ mockTotalJobsCountText = { text: '' };
37
+ mockJobsMultiStateBox = { changeState: jest.fn() };
38
+
39
+ mockW = jest.fn((selector) => {
40
+ const mocks = {
41
+ [CAREERS_MULTI_BOXES_PAGE_CONSTS.JOBS_REPEATER]: mockJobsRepeater,
42
+ [CAREERS_MULTI_BOXES_PAGE_CONSTS.paginationCurrentText]: mockPaginationCurrentText,
43
+ [CAREERS_MULTI_BOXES_PAGE_CONSTS.paginationTotalCountText]: mockPaginationTotalCountText,
44
+ [CAREERS_MULTI_BOXES_PAGE_CONSTS.PAGE_BUTTON_NEXT]: mockPageButtonNext,
45
+ [CAREERS_MULTI_BOXES_PAGE_CONSTS.PAGE_BUTTON_PREVIOUS]: mockPageButtonPrevious,
46
+ [CAREERS_MULTI_BOXES_PAGE_CONSTS.TotalJobsCountText]: mockTotalJobsCountText,
47
+ [CAREERS_MULTI_BOXES_PAGE_CONSTS.JOBS_MULTI_STATE_BOX]: mockJobsMultiStateBox
48
+ };
49
+ return mocks[selector] || {
50
+ data: null,
51
+ text: '',
52
+ value: '',
53
+ onClick: jest.fn(),
54
+ onChange: jest.fn(),
55
+ onInput: jest.fn(),
56
+ enable: jest.fn(),
57
+ disable: jest.fn(),
58
+ changeState: jest.fn()
59
+ };
60
+ });
61
+ });
62
+
63
+ afterEach(() => {
64
+ jest.clearAllMocks();
65
+ careersMultiBoxesPage.__set__('currentJobs', []);
66
+ careersMultiBoxesPage.__set__('allsecondarySearchJobs', []);
67
+ careersMultiBoxesPage.__set__('currentSecondarySearchJobs', []);
68
+ careersMultiBoxesPage.__set__('secondarySearchIsFilled', false);
69
+ });
70
+
71
+ it('should return count > 0 when searching for existing job title', async () => {
72
+
73
+
74
+ let mockJobs = MockJobBuilder.createMultiple(11, (builder, index) => {
75
+ builder.withTitle(`Product Manager ${index}`);
76
+ });
77
+
78
+ mockJobs.push(new MockJobBuilder().withTitle('Backend Engineer').build());
79
+ mockJobs.push(new MockJobBuilder().withTitle('Frontend Engineer').build());
80
+
81
+ careersMultiBoxesPage.__set__('currentJobs', mockJobs);
82
+
83
+ const result = await secondarySearch(mockW, 'product');
84
+
85
+ expect(result.length).toBe(11);
86
+ expect(mockTotalJobsCountText.text).toContain('11');
87
+ expect(mockPaginationCurrentText.text).toBe('10');
88
+ expect(mockPaginationTotalCountText.text).toBe('11');
89
+ expect(mockPageButtonNext.enable).toHaveBeenCalled();
90
+ expect(mockPageButtonPrevious.disable).toHaveBeenCalled();
91
+ });
92
+
93
+ it('should return 0 when searching for non-existing job title', async () => {
94
+ let mockJobs = MockJobBuilder.createMultiple(11, (builder, index) => {
95
+ builder.withTitle(`random job ${index}`);
96
+ });
97
+ careersMultiBoxesPage.__set__('currentJobs', mockJobs);
98
+
99
+ const result = await secondarySearch(mockW, 'unicorn hunter');
100
+
101
+ expect(result.length).toBe(0);
102
+ expect(mockTotalJobsCountText.text).toContain('0 Jobs');
103
+ expect(mockPaginationTotalCountText.text).toBe('0');
104
+ expect(mockPageButtonNext.disable).toHaveBeenCalled();
105
+ expect(mockPageButtonPrevious.disable).toHaveBeenCalled();
106
+
107
+ });
108
+
109
+ });
110
+
111
+
112
+ describe('primarySearch function tests', () => {
113
+ let mockW;
114
+ let mockprimarySearcJobResult;
115
+ let mockprimarySearchMultiBox;
116
+ let mockCategoryResultsRepeater;
117
+
118
+ beforeEach(() => {
119
+ mockprimarySearcJobResult = { data: null };
120
+ mockprimarySearchMultiBox = { changeState: jest.fn() };
121
+ mockCategoryResultsRepeater = { data: null };
122
+
123
+ mockW = jest.fn((selector) => {
124
+ const mocks = {
125
+ [CAREERS_MULTI_BOXES_PAGE_CONSTS.JOB_RESULTS_REPEATER]: mockprimarySearcJobResult,
126
+ [CAREERS_MULTI_BOXES_PAGE_CONSTS.PRIMARY_SEARCH_MULTI_BOX]: mockprimarySearchMultiBox,
127
+ [CAREERS_MULTI_BOXES_PAGE_CONSTS.CATEGORY_RESULTS_REPEATER]: mockCategoryResultsRepeater
128
+ };
129
+ return mocks[selector]
130
+ });
131
+ });
132
+
133
+ afterEach(() => {
134
+ jest.clearAllMocks();
135
+ careersMultiBoxesPage.__set__('currentJobs', []);
136
+ careersMultiBoxesPage.__set__('alljobs', []);
137
+ careersMultiBoxesPage.__set__('allvaluesobjects', []);
138
+ });
139
+
140
+ it('should show job results for existing job title', async () => {
141
+ let mockJobs = MockJobBuilder.createMultiple(11, (builder, index) => {
142
+ builder.withTitle(`Product Manager ${index}`);
143
+ });
144
+ careersMultiBoxesPage.__set__('alljobs', mockJobs);
145
+
146
+ await primarySearch(mockW, 'product',mockJobs);
147
+
148
+ expect(mockprimarySearchMultiBox.changeState).toHaveBeenCalledWith('jobResults');
149
+ expect(mockprimarySearcJobResult.data).toHaveLength(11);
150
+ expect(mockprimarySearcJobResult.data).toEqual(mockJobs);
151
+ });
152
+
153
+ it('should show no results for non-existing job title', async () => {
154
+ let mockJobs = MockJobBuilder.createMultiple(11, (builder, index) => {
155
+ builder.withTitle(`Product Manager ${index}`);
156
+ });
157
+ careersMultiBoxesPage.__set__('alljobs', mockJobs);
158
+
159
+ await primarySearch(mockW, 'unicorn hunter',mockJobs);
160
+
161
+
162
+ expect(mockprimarySearchMultiBox.changeState).toHaveBeenCalledWith('noResults');
163
+ expect(mockprimarySearcJobResult.data.length).toBe(0);
164
+ });
165
+
166
+ it('should fill category repeater when clicking on empty primary search input', async () => {
167
+ const mockCategoryValues = [
168
+ { _id: 'cat1', title: 'Engineering', customField: CATEGORY_CUSTOM_FIELD_ID_IN_CMS, count: 5 },
169
+ { _id: 'cat2', title: 'Marketing', customField: CATEGORY_CUSTOM_FIELD_ID_IN_CMS, count: 3 },
170
+ { _id: 'cat3', title: 'Sales', customField: CATEGORY_CUSTOM_FIELD_ID_IN_CMS, count: 7 }
171
+ ];
172
+
173
+ careersMultiBoxesPage.__set__('allvaluesobjects', mockCategoryValues);
174
+
175
+ await loadCategoriesListPrimarySearch(mockW,mockCategoryValues);
176
+
177
+ expect(mockprimarySearchMultiBox.changeState).toHaveBeenCalledWith('categoryResults');
178
+ expect(mockCategoryResultsRepeater.data).toHaveLength(3);
179
+ expect(mockCategoryResultsRepeater.data[0].title).toContain('Engineering (5)');
180
+ expect(mockCategoryResultsRepeater.data[1].title).toContain('Marketing (3)');
181
+ expect(mockCategoryResultsRepeater.data[2].title).toContain('Sales (7)');
182
+ });
183
+
184
+ });
185
+
186
+ describe('url params apply filters test', () => {
187
+ const categoryId = 'category-field-id';
188
+ const brandId = 'brand-field-id';
189
+ const categoryValueId = 'cat-value-123';
190
+ const brandValueId = 'brand-value-456';
191
+
192
+ let mockCategoryCheckbox;
193
+ let mockBrandsCheckbox;
194
+ let mockJobsRepeater;
195
+ let mockJobsMultiStateBox;
196
+
197
+
198
+ beforeEach(() => {
199
+
200
+ mockJobsRepeater = { data: null };
201
+ mockJobsMultiStateBox = { changeState: jest.fn() };
202
+
203
+
204
+ mockCategoryCheckbox = {
205
+ options: [
206
+ { label: 'Engineering (5)', value: categoryValueId },
207
+ { label: 'Sales (3)', value: 'other-cat' }
208
+ ],
209
+ selectedIndices: [],
210
+ value: []
211
+ };
212
+
213
+ mockBrandsCheckbox = {
214
+ options: [
215
+ { label: 'Brand A (10)', value: brandValueId },
216
+ { label: 'Brand B (5)', value: 'other-brand' }
217
+ ],
218
+ selectedIndices: [],
219
+ value: []
220
+ };
221
+
222
+ const mockFields = [
223
+ { _id: categoryId, title: 'Category' },
224
+ { _id: brandId, title: 'Brands' }
225
+ ];
226
+
227
+ const mockOptionsMap = new Map([
228
+ [categoryId, [
229
+ { label: 'Engineering', value: categoryValueId },
230
+ { label: 'Sales', value: 'other-cat' }
231
+ ]],
232
+ [brandId, [
233
+ { label: 'Brand A', value: brandValueId },
234
+ { label: 'Brand B', value: 'other-brand' }
235
+ ]]
236
+ ]);
237
+
238
+ careersMultiBoxesPage.__set__('allfields', mockFields);
239
+ careersMultiBoxesPage.__set__('optionsByFieldId', mockOptionsMap);
240
+ });
241
+
242
+ afterEach(() => {
243
+ jest.clearAllMocks();
244
+ careersMultiBoxesPage.__set__('currentJobs', []);
245
+ careersMultiBoxesPage.__set__('alljobs', []);
246
+ careersMultiBoxesPage.__set__('allfields', []);
247
+ careersMultiBoxesPage.__set__('allvaluesobjects', []);
248
+ careersMultiBoxesPage.__set__('selectedByField', new Map());
249
+ careersMultiBoxesPage.__set__('valueToJobs', {});
250
+ careersMultiBoxesPage.__set__('countsByFieldId', new Map());
251
+ careersMultiBoxesPage.__set__('optionsByFieldId', new Map());
252
+ careersMultiBoxesPage.__set__('secondarySearchIsFilled', false);
253
+ });
254
+
255
+ it.each([
256
+ {
257
+ paramName: 'brand',
258
+ paramValue: 'Brand A',
259
+ expectedCheckbox: 'brands',
260
+ expectedKeyword: 'brand a'
261
+ },
262
+ {
263
+ paramName: 'category',
264
+ paramValue: 'Engineering',
265
+ expectedCheckbox: 'category',
266
+ expectedKeyword: 'engineer'
267
+ },
268
+ {
269
+ paramName: 'keyword',
270
+ paramValue: 'senior',
271
+ expectedCheckbox: null,
272
+ expectedKeyword: 'senior'
273
+ }
274
+ ])('should apply $paramName filter when $paramName url param is present', async ({ paramName, paramValue, expectedCheckbox, expectedKeyword }) => {
275
+ const handleUrlParams = careersMultiBoxesPage.__get__('handleUrlParams');
276
+ const selectedByField = careersMultiBoxesPage.__get__('selectedByField');
277
+ const categoryValueId = 'cat-value-123';
278
+ const categoryId = 'category-field-id';
279
+ const brandId = 'brand-field-id';
280
+ const brandValueId = 'brand-value-456';
281
+
282
+ let mockPrimarySearchInput = { value: '' };
283
+ let mockPrimarySearchMultiBox = { changeState: jest.fn() };
284
+ let mockJobResultsRepeater = { data: null };
285
+
286
+ const mockWAll = jest.fn((selector) => {
287
+ const mocks = {
288
+ '#CategoryCheckBox': mockCategoryCheckbox,
289
+ '#BrandsCheckBox': mockBrandsCheckbox,
290
+ [CAREERS_MULTI_BOXES_PAGE_CONSTS.PRIMARY_SEARCH_INPUT]: mockPrimarySearchInput,
291
+ [CAREERS_MULTI_BOXES_PAGE_CONSTS.PRIMARY_SEARCH_MULTI_BOX]: mockPrimarySearchMultiBox,
292
+ [CAREERS_MULTI_BOXES_PAGE_CONSTS.JOB_RESULTS_REPEATER]: mockJobResultsRepeater,
293
+ [CAREERS_MULTI_BOXES_PAGE_CONSTS.JOBS_REPEATER]: mockJobsRepeater,
294
+ [CAREERS_MULTI_BOXES_PAGE_CONSTS.JOBS_MULTI_STATE_BOX]: mockJobsMultiStateBox
295
+ };
296
+ return mocks[selector] || {
297
+ text: '',
298
+ value: '',
299
+ data: null,
300
+ changeState: jest.fn(),
301
+ onClick: jest.fn(),
302
+ enable: jest.fn(),
303
+ disable: jest.fn()
304
+ };
305
+ });
306
+
307
+ const seniorEngineerBrandACount = Math.floor(Math.random() * 5) + 1;
308
+ const juniorEngineerBrandACount = Math.floor(Math.random() * 3) + 1;
309
+ const seniorSalesBrandBCount = Math.floor(Math.random() * 3) + 1;
310
+ const managerBrandBCount = Math.floor(Math.random() * 3) + 1;
311
+
312
+ const seniorEngineerBrandAJobs = MockJobBuilder.createJobsWithSameField(categoryValueId, seniorEngineerBrandACount, { titlePrefix: 'Senior Engineer Brand A' });
313
+ const juniorEngineerBrandAJobs = MockJobBuilder.createJobsWithSameField(categoryValueId, juniorEngineerBrandACount, { titlePrefix: 'Junior Engineer Brand A' });
314
+ const seniorSalesBrandBJobs = MockJobBuilder.createJobsWithSameField('other-cat', seniorSalesBrandBCount, { titlePrefix: 'Senior Sales Brand B' });
315
+ const managerBrandBJobs = MockJobBuilder.createJobsWithSameField('other-cat', managerBrandBCount, { titlePrefix: 'Manager Brand B' });
316
+
317
+ seniorEngineerBrandAJobs.forEach(job => job.multiRefJobsCustomValues.push({ _id: brandValueId }));
318
+ juniorEngineerBrandAJobs.forEach(job => job.multiRefJobsCustomValues.push({ _id: brandValueId }));
319
+ seniorSalesBrandBJobs.forEach(job => job.multiRefJobsCustomValues.push({ _id: 'other-brand' }));
320
+ managerBrandBJobs.forEach(job => job.multiRefJobsCustomValues.push({ _id: 'other-brand' }));
321
+
322
+ const mockJobs = [...seniorEngineerBrandAJobs, ...juniorEngineerBrandAJobs, ...seniorSalesBrandBJobs, ...managerBrandBJobs];
323
+
324
+ const brandAJobs = [...seniorEngineerBrandAJobs, ...juniorEngineerBrandAJobs];
325
+ const engineerJobs = [...seniorEngineerBrandAJobs, ...juniorEngineerBrandAJobs];
326
+ const seniorJobs = [...seniorEngineerBrandAJobs, ...seniorSalesBrandBJobs];
327
+
328
+ const valueToJobs = {
329
+ [categoryValueId]: engineerJobs.map(j => j._id),
330
+ 'other-cat': [...seniorSalesBrandBJobs, ...managerBrandBJobs].map(j => j._id),
331
+ [brandValueId]: brandAJobs.map(j => j._id),
332
+ 'other-brand': [...seniorSalesBrandBJobs, ...managerBrandBJobs].map(j => j._id)
333
+ };
334
+
335
+ const countsByFieldId = new Map([
336
+ [categoryId, new Map([
337
+ [categoryValueId, engineerJobs.length],
338
+ ['other-cat', seniorSalesBrandBCount + managerBrandBCount]
339
+ ])],
340
+ [brandId, new Map([
341
+ [brandValueId, brandAJobs.length],
342
+ ['other-brand', seniorSalesBrandBCount + managerBrandBCount]
343
+ ])]
344
+ ]);
345
+
346
+ careersMultiBoxesPage.__set__('alljobs', mockJobs);
347
+ careersMultiBoxesPage.__set__('currentJobs', mockJobs);
348
+ careersMultiBoxesPage.__set__('valueToJobs', valueToJobs);
349
+ careersMultiBoxesPage.__set__('countsByFieldId', countsByFieldId);
350
+
351
+ await handleUrlParams(mockWAll, { [paramName]: paramValue });
352
+
353
+ if (expectedCheckbox === 'brands') {
354
+ expect(mockBrandsCheckbox.selectedIndices).toEqual([0]);
355
+ expect(selectedByField.size).toBe(1);
356
+ expect(mockJobsRepeater.data).toHaveLength(brandAJobs.length);
357
+ } else if (expectedCheckbox === 'category') {
358
+ expect(mockCategoryCheckbox.selectedIndices).toEqual([0]);
359
+ expect(selectedByField.size).toBe(1);
360
+ expect(mockJobsRepeater.data).toHaveLength(engineerJobs.length);
361
+ } else {
362
+ expect(mockPrimarySearchInput.value).toBe(paramValue);
363
+ expect(mockPrimarySearchMultiBox.changeState).toHaveBeenCalledWith('jobResults');
364
+ expect(mockJobResultsRepeater.data).toHaveLength(seniorJobs.length);
365
+ }
366
+
367
+ const dataToCheck = expectedCheckbox ? mockJobsRepeater.data : mockJobResultsRepeater.data;
368
+ expect(dataToCheck.every(job => job.title.toLowerCase().includes(expectedKeyword))).toBe(true);
369
+ });
370
+ });
371
+