sr-npm 1.7.827 → 1.7.829

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sr-npm",
3
- "version": "1.7.827",
3
+ "version": "1.7.829",
4
4
  "description": "",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -25,6 +25,7 @@
25
25
  "@wix/site-window": "^1.0.0",
26
26
  "axios": "^1.11.0",
27
27
  "jest": "^30.0.5",
28
+ "psdev-utils": "1.7.3",
28
29
  "tests-utils": "^1.0.7"
29
30
  },
30
31
  "devDependencies": {
@@ -0,0 +1,12 @@
1
+
2
+ const { location } = require("@wix/site-location");
3
+ async function brandPageOnReady(_$w,brand) {
4
+ const decodedBrand = decodeURIComponent(brand);
5
+ _$w('#seeJobsButton').onClick(() => {
6
+ location.to(`/search?brand=${decodedBrand}`);
7
+ });
8
+ }
9
+
10
+ module.exports = {
11
+ brandPageOnReady,
12
+ };
@@ -69,6 +69,7 @@ async function handleUrlParams(_$w,urlParams) {
69
69
  applyFiltering=await primarySearch(_$w, decodeURIComponent(urlParams.keyword), alljobs);
70
70
  _$w(CAREERS_MULTI_BOXES_PAGE_CONSTS.PRIMARY_SEARCH_INPUT).value=decodeURIComponent(urlParams.keyword);
71
71
  keyword=true;
72
+ console.log("delete me")
72
73
  }
73
74
  if(applyFiltering) {
74
75
  await updateJobsAndNumbersAndFilters(_$w,false,keyword);
@@ -198,8 +199,8 @@ async function loadJobsRepeater(_$w) {
198
199
  try {
199
200
  _$w(CAREERS_MULTI_BOXES_PAGE_CONSTS.JOBS_REPEATER).onItemReady(($item, itemData) => {
200
201
  $item(CAREERS_MULTI_BOXES_PAGE_CONSTS.JOBS_REPEATER_ITEM_TITLE).text = itemData.title;
201
- $item(CAREERS_MULTI_BOXES_PAGE_CONSTS.JOBS_REPEATER_ITEM_TITLE).onClick(async () => {
202
- await location.to(itemData["link-jobs-title"]);
202
+ $item(CAREERS_MULTI_BOXES_PAGE_CONSTS.JOBS_REPEATER_ITEM_TITLE).onClick(() => {
203
+ location.to(itemData["link-jobs-title"]);
203
204
  });
204
205
  $item(CAREERS_MULTI_BOXES_PAGE_CONSTS.JOBS_REPEATER_ITEM_LOCATION).text=itemData.location.fullLocation
205
206
  $item(CAREERS_MULTI_BOXES_PAGE_CONSTS.JOBS_REPEATER_ITEM_EMPLOYMENT_TYPE).text=itemData.employmentType
package/pages/index.js CHANGED
@@ -4,6 +4,7 @@ module.exports = {
4
4
  ...require('./careersPage'),
5
5
  ...require('./careersMultiBoxesPage'),
6
6
  ...require('./pagesUtils'),
7
+ ...require('./brandPage'),
7
8
  ...require('./supportTeamsPage'),
8
9
  };
9
10
 
@@ -64,8 +64,8 @@ async function loadPrimarySearchRepeater(_$w) {
64
64
  try {
65
65
  _$w(CAREERS_MULTI_BOXES_PAGE_CONSTS.JOB_RESULTS_REPEATER).onItemReady(async ($item, itemData) => {
66
66
  $item(CAREERS_MULTI_BOXES_PAGE_CONSTS.PRIMARY_SEARCH_POSITION_BUTTON).label = itemData.title || '';
67
- $item(CAREERS_MULTI_BOXES_PAGE_CONSTS.PRIMARY_SEARCH_POSITION_BUTTON).onClick(async () => {
68
- await location.to(itemData["link-jobs-title"]);
67
+ $item(CAREERS_MULTI_BOXES_PAGE_CONSTS.PRIMARY_SEARCH_POSITION_BUTTON).onClick(() => {
68
+ location.to(itemData["link-jobs-title"]);
69
69
  })
70
70
 
71
71
  });
@@ -75,7 +75,7 @@ async function loadPrimarySearchRepeater(_$w) {
75
75
  $item(CAREERS_MULTI_BOXES_PAGE_CONSTS.PRIMARY_SEARCH_CATEGORY_BUTTON).onClick(async () => {
76
76
  const baseUrl = await location.baseUrl();
77
77
  const encodedCategory=encodeURIComponent(itemData._id);
78
- await location.to(`${baseUrl}/search?category=${encodedCategory}`);
78
+ location.to(`${baseUrl}/search?category=${encodedCategory}`);
79
79
  });
80
80
  });
81
81
  } catch (error) {
@@ -118,7 +118,7 @@ _$w(CAREERS_MULTI_BOXES_PAGE_CONSTS.PRIMARY_SEARCH_INPUT).onKeyPress(async (even
118
118
  else {
119
119
  let encodedKeyWord=encodeURIComponent(_$w(CAREERS_MULTI_BOXES_PAGE_CONSTS.PRIMARY_SEARCH_INPUT).value);
120
120
  const baseUrl = await location.baseUrl();
121
- await location.to(`${baseUrl}/search?keyword=${encodedKeyWord}`);
121
+ location.to(`${baseUrl}/search?keyword=${encodedKeyWord}`);
122
122
  // queryParams.add({ keyword:encodedKeyWord });
123
123
  // handleUrlParams(_$w,{keyword:encodedKeyWord});
124
124
  // _$w(CAREERS_MULTI_BOXES_PAGE_CONSTS.RESULTS_CONTAINER).collapse();
@@ -135,7 +135,7 @@ _$w(CAREERS_MULTI_BOXES_PAGE_CONSTS.PRIMARY_SEARCH_BUTTON).onClick(async () => {
135
135
  else {
136
136
  let encodedKeyWord=encodeURIComponent(_$w(CAREERS_MULTI_BOXES_PAGE_CONSTS.PRIMARY_SEARCH_INPUT).value);
137
137
  const baseUrl = await location.baseUrl();
138
- await location.to(`${baseUrl}/search?keyword=${encodedKeyWord}`);
138
+ location.to(`${baseUrl}/search?keyword=${encodedKeyWord}`);
139
139
  // queryParams.add({ keyword:encodedKeyWord });
140
140
  // await primarySearch(_$w, _$w(CAREERS_MULTI_BOXES_PAGE_CONSTS.PRIMARY_SEARCH_INPUT).value.trim());
141
141
  // _$w(CAREERS_MULTI_BOXES_PAGE_CONSTS.RESULTS_CONTAINER).collapse();
@@ -3,6 +3,7 @@ const { getPositionWithMultiRefField } = require('../backend/queries');
3
3
  const { COLLECTIONS,JOBS_COLLECTION_FIELDS,CUSTOM_FIELDS_COLLECTION_FIELDS } = require('../backend/collectionConsts');
4
4
  const { items: wixData } = require('@wix/data');
5
5
  const { location } = require("@wix/site-location");
6
+ const{isElementExistOnPage} = require('psdev-utils');
6
7
  const {
7
8
  htmlToText,
8
9
  appendQueryParams
@@ -19,12 +20,11 @@ const {
19
20
 
20
21
  }
21
22
 
22
- async function getCategoryValueId(customFields) {
23
- console.log("customFields: ", customFields);
23
+ async function getCategoryValueId(customValues) {
24
24
  const categoryCustomField=await wixData.query(COLLECTIONS.CUSTOM_FIELDS).eq(CUSTOM_FIELDS_COLLECTION_FIELDS.TITLE,"Category").find().then(result => result.items[0]);
25
- for(const field of customFields) {
26
- if(field.customField===categoryCustomField._id) {
27
- return field._id;
25
+ for(const value of customValues) {
26
+ if(value.customField===categoryCustomField._id) {
27
+ return value._id;
28
28
 
29
29
  }
30
30
  }
@@ -36,7 +36,6 @@ async function getCategoryValueId(customFields) {
36
36
 
37
37
  const item = await _$w('#datasetJobsItem').getCurrentItem();
38
38
  const multiRefField=await getPositionWithMultiRefField(item._id);
39
- console.log("multiRefField: ", multiRefField);
40
39
  const categoryValueId=await getCategoryValueId(multiRefField);
41
40
 
42
41
  handleReferFriendButton(_$w,item);
@@ -47,7 +46,7 @@ async function getCategoryValueId(customFields) {
47
46
  _$w('#responsibilitiesText').text = htmlToText(item.jobDescription.jobDescription.text);
48
47
  _$w('#qualificationsText').text = htmlToText(item.jobDescription.qualifications.text);
49
48
  _$w('#relatedJobsTitleText').text = `More ${item.department} Positions`;
50
- if(_$w('#additionalInfoText'))
49
+ if(isElementExistOnPage(_$w('#additionalInfoText')))
51
50
  {
52
51
  _$w('#additionalInfoText').text = htmlToText(item.jobDescription.additionalInformation.text);
53
52
  }
@@ -70,7 +69,7 @@ async function getCategoryValueId(customFields) {
70
69
  );
71
70
  location.to(clickedItemData["link-jobs-title"]);
72
71
  });
73
- if(_$w('#relatedJobsDataset') && _$w('#relatedJobsDataset').length>0)
72
+ if(isElementExistOnPage(_$w('#relatedJobsDataset')))
74
73
  {
75
74
  _$w('#relatedJobsDataset').onReady(() => {
76
75
  const count = _$w('#relatedJobsDataset').getTotalCount();
@@ -83,7 +82,7 @@ async function getCategoryValueId(customFields) {
83
82
  }
84
83
 
85
84
  function handleReferFriendButton(_$w,item) {
86
- if(!item.referFriendLink && _$w('#referFriendButton')){
85
+ if(!item.referFriendLink && isElementExistOnPage(_$w('#referFriendButton'))){
87
86
  console.log("hiding referFriendButton");
88
87
  _$w('#referFriendButton').hide();
89
88
  }
@@ -26,15 +26,15 @@ async function handleRecentJobsSection(_$w) {
26
26
  _$w(supportTeamsPageIds.RECENTLEY_ADDED_JOBS).onItemReady(($item, itemData) => {
27
27
  $item(supportTeamsPageIds.JOB_TITLE).text = itemData.title;
28
28
  $item(supportTeamsPageIds.JOB_LOCATION).text = itemData.location.fullLocation;
29
- $item(supportTeamsPageIds.JOB_TITLE).onClick(async () => {
30
- await location.to(itemData["link-jobs-title"]);
29
+ $item(supportTeamsPageIds.JOB_TITLE).onClick( () => {
30
+ location.to(itemData["link-jobs-title"]);
31
31
  })
32
32
  });
33
33
 
34
34
  _$w(supportTeamsPageIds.RECENTLEY_ADDED_JOBS).data = latestsJobs;
35
35
 
36
- _$w(supportTeamsPageIds.SEE_ALL_JOBS_TEXT).onClick(async () => {
37
- await location.to(`/search?category=${Value.title}`);
36
+ _$w(supportTeamsPageIds.SEE_ALL_JOBS_TEXT).onClick( () => {
37
+ location.to(`/search?category=${Value.title}`);
38
38
  });
39
39
  }
40
40
 
@@ -0,0 +1,45 @@
1
+ const mockLocation = {
2
+ to: jest.fn()
3
+ };
4
+
5
+ jest.mock('@wix/site-location', () => ({
6
+ location: mockLocation
7
+ }));
8
+
9
+ const { brandPageOnReady } = require('../pages/brandPage');
10
+
11
+ describe('Brand Page Tests', () => {
12
+ let mockW;
13
+ let mockButton;
14
+
15
+ beforeEach(() => {
16
+ jest.clearAllMocks();
17
+
18
+ mockButton = {
19
+ onClick: jest.fn()
20
+ };
21
+
22
+ mockW = jest.fn((selector) => {
23
+ if (selector === '#seeJobsButton') {
24
+ return mockButton;
25
+ }
26
+ return {};
27
+ });
28
+ });
29
+
30
+ it('should navigate to search page with brand param when all jobs button is clicked', async () => {
31
+ const brandName = 'TestBrand';
32
+
33
+ await brandPageOnReady(mockW, brandName);
34
+
35
+ expect(mockButton.onClick).toHaveBeenCalled();
36
+
37
+ const onClickCallback = mockButton.onClick.mock.calls[0][0];
38
+ await onClickCallback();
39
+
40
+ expect(mockLocation.to).toHaveBeenCalledWith(`/search?brand=${brandName}`);
41
+ });
42
+
43
+
44
+ });
45
+
@@ -238,7 +238,12 @@ class MockJobBuilder {
238
238
  return jobs;
239
239
  }
240
240
 
241
- static createJobsWithSameCategory(categoryId, count = 3) {
241
+ static createJobsWithSameField(fieldId, count = 3,options = {}) {
242
+ const {
243
+ titlePrefix = null,
244
+ randomTitles = true
245
+ } = options;
246
+
242
247
  const jobs = [];
243
248
  const titles = [
244
249
  'Frontend Developer', 'Backend Developer', 'Full Stack Engineer',
@@ -254,18 +259,28 @@ class MockJobBuilder {
254
259
  ];
255
260
 
256
261
  for (let i = 0; i < count; i++) {
257
- const randomTitle = titles[Math.floor(Math.random() * titles.length)];
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
+
258
272
  const randomCity = cities[Math.floor(Math.random() * cities.length)];
259
273
 
260
- jobs.push(
261
- new MockJobBuilder()
262
- .withTitle(`${randomTitle} ${i + 1}`)
263
- .withCity(randomCity.city, randomCity.region)
264
- .withCategory(categoryId)
265
- .withLinkJobsTitle(`/jobs/${randomTitle.toLowerCase().replace(/\s+/g, '-')}-${i + 1}`)
266
- .forPositionPage()
267
- .build()
268
- );
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);
269
284
  }
270
285
  return jobs;
271
286
  }
@@ -2,43 +2,15 @@ const rewire = require('rewire');
2
2
  const MockJobBuilder = require('./mockJobBuilder');
3
3
  const { CAREERS_MULTI_BOXES_PAGE_CONSTS, CATEGORY_CUSTOM_FIELD_ID_IN_CMS } = require('../backend/careersMultiBoxesPageIds');
4
4
 
5
- // Mock Wix modules
6
- const mockQueryParams = {
7
- add: jest.fn(),
8
- remove: jest.fn()
9
- };
10
-
11
- const mockLocation = {
12
- url: 'https://test.com',
13
- path: '/test',
14
- query: {}
15
- };
16
-
17
- // Temporarily mock require for Wix modules
18
- const Module = require('module');
19
- const originalRequire = Module.prototype.require;
20
- Module.prototype.require = function(id) {
21
- if (id === 'wix-location-frontend') {
22
- return { queryParams: mockQueryParams };
23
- }
24
- if (id === '@wix/site-location') {
25
- return { location: mockLocation };
26
- }
27
- return originalRequire.apply(this, arguments);
28
- };
29
-
5
+ // Load modules with rewire
30
6
  const careersMultiBoxesPage = rewire('../pages/careersMultiBoxesPage');
31
7
  const pagesUtils = rewire('../pages/pagesUtils');
32
8
 
33
- // Restore original require
34
- Module.prototype.require = originalRequire;
35
-
36
9
  const secondarySearch = careersMultiBoxesPage.__get__('secondarySearch');
37
10
  const primarySearch = pagesUtils.__get__('primarySearch');
38
11
  const loadCategoriesListPrimarySearch = pagesUtils.__get__('loadCategoriesListPrimarySearch');
39
12
 
40
13
 
41
-
42
14
  describe('secondarySearch function tests', () => {
43
15
  let mockW;
44
16
  let mockJobsRepeater;
@@ -91,6 +63,9 @@ describe('secondarySearch function tests', () => {
91
63
  afterEach(() => {
92
64
  jest.clearAllMocks();
93
65
  careersMultiBoxesPage.__set__('currentJobs', []);
66
+ careersMultiBoxesPage.__set__('allsecondarySearchJobs', []);
67
+ careersMultiBoxesPage.__set__('currentSecondarySearchJobs', []);
68
+ careersMultiBoxesPage.__set__('secondarySearchIsFilled', false);
94
69
  });
95
70
 
96
71
  it('should return count > 0 when searching for existing job title', async () => {
@@ -158,6 +133,8 @@ describe('primarySearch function tests', () => {
158
133
  afterEach(() => {
159
134
  jest.clearAllMocks();
160
135
  careersMultiBoxesPage.__set__('currentJobs', []);
136
+ careersMultiBoxesPage.__set__('alljobs', []);
137
+ careersMultiBoxesPage.__set__('allvaluesobjects', []);
161
138
  });
162
139
 
163
140
  it('should show job results for existing job title', async () => {
@@ -204,4 +181,190 @@ describe('primarySearch function tests', () => {
204
181
  });
205
182
 
206
183
  });
184
+
185
+ describe('url params apply filters test', () => {
186
+ const categoryId = 'category-field-id';
187
+ const brandId = 'brand-field-id';
188
+ const categoryValueId = 'cat-value-123';
189
+ const brandValueId = 'brand-value-456';
190
+
191
+ let mockCategoryCheckbox;
192
+ let mockBrandsCheckbox;
193
+ let mockJobsRepeater;
194
+ let mockJobsMultiStateBox;
195
+
196
+
197
+ beforeEach(() => {
198
+
199
+ mockJobsRepeater = { data: null };
200
+ mockJobsMultiStateBox = { changeState: jest.fn() };
201
+
202
+
203
+ mockCategoryCheckbox = {
204
+ options: [
205
+ { label: 'Engineering (5)', value: categoryValueId },
206
+ { label: 'Sales (3)', value: 'other-cat' }
207
+ ],
208
+ selectedIndices: [],
209
+ value: []
210
+ };
211
+
212
+ mockBrandsCheckbox = {
213
+ options: [
214
+ { label: 'Brand A (10)', value: brandValueId },
215
+ { label: 'Brand B (5)', value: 'other-brand' }
216
+ ],
217
+ selectedIndices: [],
218
+ value: []
219
+ };
220
+
221
+ const mockFields = [
222
+ { _id: categoryId, title: 'Category' },
223
+ { _id: brandId, title: 'Brands' }
224
+ ];
225
+
226
+ const mockOptionsMap = new Map([
227
+ [categoryId, [
228
+ { label: 'Engineering', value: categoryValueId },
229
+ { label: 'Sales', value: 'other-cat' }
230
+ ]],
231
+ [brandId, [
232
+ { label: 'Brand A', value: brandValueId },
233
+ { label: 'Brand B', value: 'other-brand' }
234
+ ]]
235
+ ]);
236
+
237
+ careersMultiBoxesPage.__set__('allfields', mockFields);
238
+ careersMultiBoxesPage.__set__('optionsByFieldId', mockOptionsMap);
239
+ });
240
+
241
+ afterEach(() => {
242
+ jest.clearAllMocks();
243
+ careersMultiBoxesPage.__set__('currentJobs', []);
244
+ careersMultiBoxesPage.__set__('alljobs', []);
245
+ careersMultiBoxesPage.__set__('allfields', []);
246
+ careersMultiBoxesPage.__set__('allvaluesobjects', []);
247
+ careersMultiBoxesPage.__set__('selectedByField', new Map());
248
+ careersMultiBoxesPage.__set__('valueToJobs', {});
249
+ careersMultiBoxesPage.__set__('countsByFieldId', new Map());
250
+ careersMultiBoxesPage.__set__('optionsByFieldId', new Map());
251
+ careersMultiBoxesPage.__set__('secondarySearchIsFilled', false);
252
+ });
253
+
254
+ it.each([
255
+ {
256
+ paramName: 'brand',
257
+ paramValue: 'Brand A',
258
+ expectedCheckbox: 'brands',
259
+ expectedKeyword: 'brand a'
260
+ },
261
+ {
262
+ paramName: 'category',
263
+ paramValue: 'Engineering',
264
+ expectedCheckbox: 'category',
265
+ expectedKeyword: 'engineer'
266
+ },
267
+ {
268
+ paramName: 'keyword',
269
+ paramValue: 'senior',
270
+ expectedCheckbox: null,
271
+ expectedKeyword: 'senior'
272
+ }
273
+ ])('should apply $paramName filter when $paramName url param is present', async ({ paramName, paramValue, expectedCheckbox, expectedKeyword }) => {
274
+ const handleUrlParams = careersMultiBoxesPage.__get__('handleUrlParams');
275
+ const selectedByField = careersMultiBoxesPage.__get__('selectedByField');
276
+ const categoryValueId = 'cat-value-123';
277
+ const categoryId = 'category-field-id';
278
+ const brandId = 'brand-field-id';
279
+ const brandValueId = 'brand-value-456';
280
+
281
+ let mockPrimarySearchInput = { value: '' };
282
+ let mockPrimarySearchMultiBox = { changeState: jest.fn() };
283
+ let mockJobResultsRepeater = { data: null };
284
+
285
+ const mockWAll = jest.fn((selector) => {
286
+ const mocks = {
287
+ '#CategoryCheckBox': mockCategoryCheckbox,
288
+ '#BrandsCheckBox': mockBrandsCheckbox,
289
+ [CAREERS_MULTI_BOXES_PAGE_CONSTS.PRIMARY_SEARCH_INPUT]: mockPrimarySearchInput,
290
+ [CAREERS_MULTI_BOXES_PAGE_CONSTS.PRIMARY_SEARCH_MULTI_BOX]: mockPrimarySearchMultiBox,
291
+ [CAREERS_MULTI_BOXES_PAGE_CONSTS.JOB_RESULTS_REPEATER]: mockJobResultsRepeater,
292
+ [CAREERS_MULTI_BOXES_PAGE_CONSTS.JOBS_REPEATER]: mockJobsRepeater,
293
+ [CAREERS_MULTI_BOXES_PAGE_CONSTS.JOBS_MULTI_STATE_BOX]: mockJobsMultiStateBox
294
+ };
295
+ return mocks[selector] || {
296
+ text: '',
297
+ value: '',
298
+ data: null,
299
+ changeState: jest.fn(),
300
+ onClick: jest.fn(),
301
+ enable: jest.fn(),
302
+ disable: jest.fn()
303
+ };
304
+ });
305
+
306
+ const seniorEngineerBrandACount = Math.floor(Math.random() * 5) + 1;
307
+ const juniorEngineerBrandACount = Math.floor(Math.random() * 3) + 1;
308
+ const seniorSalesBrandBCount = Math.floor(Math.random() * 3) + 1;
309
+ const managerBrandBCount = Math.floor(Math.random() * 3) + 1;
310
+
311
+ const seniorEngineerBrandAJobs = MockJobBuilder.createJobsWithSameField(categoryValueId, seniorEngineerBrandACount, { titlePrefix: 'Senior Engineer Brand A' });
312
+ const juniorEngineerBrandAJobs = MockJobBuilder.createJobsWithSameField(categoryValueId, juniorEngineerBrandACount, { titlePrefix: 'Junior Engineer Brand A' });
313
+ const seniorSalesBrandBJobs = MockJobBuilder.createJobsWithSameField('other-cat', seniorSalesBrandBCount, { titlePrefix: 'Senior Sales Brand B' });
314
+ const managerBrandBJobs = MockJobBuilder.createJobsWithSameField('other-cat', managerBrandBCount, { titlePrefix: 'Manager Brand B' });
315
+
316
+ seniorEngineerBrandAJobs.forEach(job => job.multiRefJobsCustomValues.push({ _id: brandValueId }));
317
+ juniorEngineerBrandAJobs.forEach(job => job.multiRefJobsCustomValues.push({ _id: brandValueId }));
318
+ seniorSalesBrandBJobs.forEach(job => job.multiRefJobsCustomValues.push({ _id: 'other-brand' }));
319
+ managerBrandBJobs.forEach(job => job.multiRefJobsCustomValues.push({ _id: 'other-brand' }));
320
+
321
+ const mockJobs = [...seniorEngineerBrandAJobs, ...juniorEngineerBrandAJobs, ...seniorSalesBrandBJobs, ...managerBrandBJobs];
322
+
323
+ const brandAJobs = [...seniorEngineerBrandAJobs, ...juniorEngineerBrandAJobs];
324
+ const engineerJobs = [...seniorEngineerBrandAJobs, ...juniorEngineerBrandAJobs];
325
+ const seniorJobs = [...seniorEngineerBrandAJobs, ...seniorSalesBrandBJobs];
326
+
327
+ const valueToJobs = {
328
+ [categoryValueId]: engineerJobs.map(j => j._id),
329
+ 'other-cat': [...seniorSalesBrandBJobs, ...managerBrandBJobs].map(j => j._id),
330
+ [brandValueId]: brandAJobs.map(j => j._id),
331
+ 'other-brand': [...seniorSalesBrandBJobs, ...managerBrandBJobs].map(j => j._id)
332
+ };
333
+
334
+ const countsByFieldId = new Map([
335
+ [categoryId, new Map([
336
+ [categoryValueId, engineerJobs.length],
337
+ ['other-cat', seniorSalesBrandBCount + managerBrandBCount]
338
+ ])],
339
+ [brandId, new Map([
340
+ [brandValueId, brandAJobs.length],
341
+ ['other-brand', seniorSalesBrandBCount + managerBrandBCount]
342
+ ])]
343
+ ]);
344
+
345
+ careersMultiBoxesPage.__set__('alljobs', mockJobs);
346
+ careersMultiBoxesPage.__set__('currentJobs', mockJobs);
347
+ careersMultiBoxesPage.__set__('valueToJobs', valueToJobs);
348
+ careersMultiBoxesPage.__set__('countsByFieldId', countsByFieldId);
349
+
350
+ await handleUrlParams(mockWAll, { [paramName]: paramValue });
351
+
352
+ if (expectedCheckbox === 'brands') {
353
+ expect(mockBrandsCheckbox.selectedIndices).toEqual([0]);
354
+ expect(selectedByField.size).toBe(1);
355
+ expect(mockJobsRepeater.data).toHaveLength(brandAJobs.length);
356
+ } else if (expectedCheckbox === 'category') {
357
+ expect(mockCategoryCheckbox.selectedIndices).toEqual([0]);
358
+ expect(selectedByField.size).toBe(1);
359
+ expect(mockJobsRepeater.data).toHaveLength(engineerJobs.length);
360
+ } else {
361
+ expect(mockPrimarySearchInput.value).toBe(paramValue);
362
+ expect(mockPrimarySearchMultiBox.changeState).toHaveBeenCalledWith('jobResults');
363
+ expect(mockJobResultsRepeater.data).toHaveLength(seniorJobs.length);
364
+ }
365
+
366
+ const dataToCheck = expectedCheckbox ? mockJobsRepeater.data : mockJobResultsRepeater.data;
367
+ expect(dataToCheck.every(job => job.title.toLowerCase().includes(expectedKeyword))).toBe(true);
368
+ });
369
+ });
207
370
 
@@ -1,6 +1,9 @@
1
+ // Mock query chain at the top
1
2
  const MockJobBuilder = require('./mockJobBuilder');
3
+ const { positionPageOnReady } = require('../pages/positionPage');
4
+ const { getPositionWithMultiRefField } = require('../backend/queries');
5
+ const { items: wixData } = require('@wix/data');
2
6
 
3
- // Create mocks before importing
4
7
  const mockQueryChain = {
5
8
  eq: jest.fn().mockReturnThis(),
6
9
  find: jest.fn(),
@@ -11,16 +14,15 @@ const mockQueryChain = {
11
14
  then: jest.fn()
12
15
  };
13
16
 
14
- const mockWixData = {
15
- query: jest.fn(() => mockQueryChain),
16
- queryReferenced: jest.fn()
17
- };
18
-
17
+ // Jest mocks (hoisted automatically)
19
18
  jest.mock('wix-location-frontend', () => ({
20
19
  query: {}
21
20
  }), { virtual: true });
22
21
  jest.mock('@wix/data', () => ({
23
- items: mockWixData
22
+ items: {
23
+ query: jest.fn(() => mockQueryChain),
24
+ queryReferenced: jest.fn()
25
+ }
24
26
  }));
25
27
  jest.mock('@wix/site-location', () => ({
26
28
  location: {
@@ -39,8 +41,14 @@ jest.mock('../public/utils', () => ({
39
41
  appendQueryParams: jest.fn((url) => url)
40
42
  }));
41
43
 
42
- const { positionPageOnReady } = require('../pages/positionPage');
43
- const { getPositionWithMultiRefField } = require('../backend/queries');
44
+ // Mock isElementExistOnPage
45
+ jest.mock('psdev-utils', () => ({
46
+ isElementExistOnPage: jest.fn(() => true)
47
+ }));
48
+
49
+
50
+
51
+
44
52
 
45
53
 
46
54
  describe('related jobs show jobs with the same category value test', () => {
@@ -59,22 +67,17 @@ describe('related jobs show jobs with the same category value test', () => {
59
67
  const CATEGORY_FIELD_ID = `category-field-${Date.now()}`;
60
68
  const TECH_CATEGORY_VALUE_ID = `tech-category-${Math.floor(Math.random() * 10000)}`;
61
69
 
62
- // Create current job using MockJobBuilder with random data
63
70
  const currentJob = new MockJobBuilder()
64
71
  .withTitle('Senior Developer')
65
72
  .withDepartment('Technology')
66
- .withCategory(TECH_CATEGORY_VALUE_ID)
73
+ .withMultiRefCustomValues([{ _id: TECH_CATEGORY_VALUE_ID }])
67
74
  .forPositionPage()
68
75
  .build();
69
76
 
70
- // Create 0-5 related jobs with same category using random data (including case with 0 related jobs)
71
- const relatedJobsCount = Math.floor(Math.random() * 6); // 0-5 jobs
72
- const relatedJobs = MockJobBuilder.createJobsWithSameCategory(
73
- TECH_CATEGORY_VALUE_ID,
74
- relatedJobsCount
75
- );
77
+ // create 0-5 related jobs with same category value(0 for the case when there is no related jobs)
78
+ const relatedJobsCount = Math.floor(Math.random() * 6);
79
+ const relatedJobs = MockJobBuilder.createJobsWithSameField(TECH_CATEGORY_VALUE_ID, relatedJobsCount);
76
80
 
77
- // Current job's custom values (Tech category)
78
81
  const currentJobCustomValues = [
79
82
  { _id: TECH_CATEGORY_VALUE_ID, customField: CATEGORY_FIELD_ID, title: 'Technology' }
80
83
  ];
@@ -84,7 +87,6 @@ describe('related jobs show jobs with the same category value test', () => {
84
87
  title: 'Category'
85
88
  };
86
89
 
87
- // Setup mocks - capture the onReady callback so we can await it
88
90
  let datasetReadyCallback;
89
91
  const mockDataset = {
90
92
  onReady: jest.fn((callback) => {
@@ -102,35 +104,34 @@ describe('related jobs show jobs with the same category value test', () => {
102
104
  '#qualificationsText': { text: '' },
103
105
  '#relatedJobsTitleText': { text: '' },
104
106
  '#additionalInfoText': { text: '' },
105
- '#applyButton': { target: '', link: '' }
107
+ '#applyButton': { target: '', link: '' },
108
+ '#relatedJobsNoDepartmentItem': { onClick: jest.fn() },
109
+ '#relatedJobsDataset': { onReady: jest.fn(), getTotalCount: jest.fn() },
110
+ '#relatedJobsSection': { collapse: jest.fn() },
111
+ '#referFriendButton': { hide: jest.fn() }
106
112
  };
107
- return mocks[selector] || { text: '', hide: jest.fn() };
113
+ return mocks[selector] || { text: '', hide: jest.fn(), onClick: jest.fn() };
108
114
  });
109
115
 
110
116
  getPositionWithMultiRefField.mockResolvedValue(currentJobCustomValues);
111
117
 
112
118
  mockQueryChain.find.mockImplementation(() => {
113
- const queryArg = mockWixData.query.mock.calls[mockWixData.query.mock.calls.length - 1][0];
119
+ const queryArg = wixData.query.mock.calls[wixData.query.mock.calls.length - 1][0];
114
120
  if (queryArg === 'CustomFields') {
115
121
  return Promise.resolve({ items: [categoryCustomField] });
116
122
  }
117
123
  return Promise.resolve({ items: relatedJobs });
118
124
  });
119
125
 
120
- // Run the page function (sets up the onReady callback)
121
126
  await positionPageOnReady(mockW);
122
-
123
- // Now execute the dataset onReady callback and wait for it
124
127
  await datasetReadyCallback();
125
128
 
126
- // Verify the repeater got populated with related jobs
127
129
  expect(mockRealtedJobsRepeater.data).not.toBeNull();
128
130
  expect(mockRealtedJobsRepeater.data).toHaveLength(relatedJobsCount);
129
131
 
130
- // Verify all related jobs have the same category as current job
131
132
  const allHaveSameCategory = mockRealtedJobsRepeater.data.every(job =>
132
133
  job.multiRefJobsCustomValues &&
133
- job.multiRefJobsCustomValues.includes(TECH_CATEGORY_VALUE_ID)
134
+ job.multiRefJobsCustomValues.some(val => val._id === TECH_CATEGORY_VALUE_ID)
134
135
  );
135
136
  expect(allHaveSameCategory).toBe(true);
136
137
  });