sr-npm 1.7.771 → 1.7.773

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.771",
3
+ "version": "1.7.773",
4
4
  "description": "",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -23,16 +23,20 @@ const pagination = {
23
23
  async function careersMultiBoxesPageOnReady(_$w,urlParams) {
24
24
  console.log("careersMultiBoxesPageOnReady urlParams: ", urlParams);
25
25
  await loadData(_$w);
26
- await loadJobsRepeater(_$w);
27
- await loadPrimarySearchRepeater(_$w);
28
- await loadFilters(_$w);
29
- await loadSelectedValuesRepeater(_$w);
30
- await bindSearchInput(_$w);
26
+
27
+ await Promise.all([
28
+ loadJobsRepeater(_$w),
29
+ loadPrimarySearchRepeater(_$w),
30
+ loadFilters(_$w),
31
+ loadSelectedValuesRepeater(_$w),
32
+ bindSearchInput(_$w),
33
+ loadPaginationButtons(_$w)
34
+ ]);
35
+ await handleUrlParams(_$w, urlParams);
31
36
  _$w(CAREERS_MULTI_BOXES_PAGE_CONSTS.CLEAR_ALL_BUTTON_ID).onClick(async () => {
32
37
  await clearAll(_$w);
33
38
  });
34
- await loadPaginationButtons(_$w);
35
- await handleUrlParams(_$w,urlParams);
39
+
36
40
  }
37
41
 
38
42
  async function clearAll(_$w) {
@@ -51,6 +55,7 @@ async function clearAll(_$w) {
51
55
 
52
56
 
53
57
  async function loadPrimarySearchRepeater(_$w) {
58
+ try {
54
59
  _$w(CAREERS_MULTI_BOXES_PAGE_CONSTS.JOB_RESULTS_REPEATER).onItemReady(async ($item, itemData) => {
55
60
  $item(CAREERS_MULTI_BOXES_PAGE_CONSTS.PRIMARY_SEARCH_POSITION_BUTTON).label = itemData.title || '';
56
61
  $item(CAREERS_MULTI_BOXES_PAGE_CONSTS.PRIMARY_SEARCH_POSITION_BUTTON).onClick(async () => {
@@ -69,9 +74,13 @@ async function loadPrimarySearchRepeater(_$w) {
69
74
  await handleUrlParams(_$w,{category:encodedCategory});
70
75
  });
71
76
  });
77
+ } catch (error) {
78
+ console.error('Failed to load primary search repeater:', error);
79
+ }
72
80
  }
73
81
 
74
82
  async function handleUrlParams(_$w,urlParams) {
83
+ try {
75
84
  let applyFiltering=false;
76
85
  let keyword=false
77
86
  console.log("handleUrlParams urlParams: ", urlParams);
@@ -108,6 +117,9 @@ async function handleUrlParams(_$w,urlParams) {
108
117
  _$w(CAREERS_MULTI_BOXES_PAGE_CONSTS.JOBS_REPEATER).data = jobsFirstPage;
109
118
  handlePaginationButtons(_$w);
110
119
  }
120
+ } catch (error) {
121
+ console.error('Failed to handle url params:', error);
122
+ }
111
123
  }
112
124
 
113
125
  async function handleParams(_$w,param,value) {
@@ -133,6 +145,7 @@ async function handleParams(_$w,param,value) {
133
145
  }
134
146
 
135
147
  async function loadPaginationButtons(_$w) {
148
+ try {
136
149
  _$w(CAREERS_MULTI_BOXES_PAGE_CONSTS.PAGE_BUTTON_NEXT).onClick(async () => {
137
150
  let nextPageJobs=currentJobs.slice(pagination.pageSize*pagination.currentPage,pagination.pageSize*(pagination.currentPage+1));
138
151
  _$w(CAREERS_MULTI_BOXES_PAGE_CONSTS.paginationCurrentText).text = (nextPageJobs.length+pagination.pageSize*pagination.currentPage).toString();
@@ -148,9 +161,13 @@ async function loadPaginationButtons(_$w) {
148
161
  _$w(CAREERS_MULTI_BOXES_PAGE_CONSTS.JOBS_REPEATER).data = previousPageJobs;
149
162
  handlePaginationButtons(_$w);
150
163
  });
164
+ } catch (error) {
165
+ console.error('Failed to load pagination buttons:', error);
166
+ }
151
167
  }
152
168
 
153
169
  async function loadSelectedValuesRepeater(_$w) {
170
+ try {
154
171
  _$w(CAREERS_MULTI_BOXES_PAGE_CONSTS.SELECTED_VALUES_REPEATER).onItemReady(($item, itemData) => {
155
172
  $item(CAREERS_MULTI_BOXES_PAGE_CONSTS.SELECTED_VALUES_REPEATER_ITEM_LABEL).text = itemData.label || '';
156
173
  // Deselect this value from both the selected map and the multibox
@@ -177,16 +194,19 @@ async function loadSelectedValuesRepeater(_$w) {
177
194
  });
178
195
  });
179
196
  await updateSelectedValuesRepeater(_$w);
197
+ } catch (error) {
198
+ console.error('Failed to load selected values repeater:', error);
199
+ }
180
200
  }
181
201
 
182
- async function loadData(_$w) {
202
+ async function loadData() {
203
+ try {
183
204
  if(alljobs.length===0) {
184
205
  alljobs=await getAllRecords(COLLECTIONS.JOBS);
185
206
  currentJobs=alljobs;
186
207
  }
187
208
  if(Object.keys(valueToJobs).length === 0){
188
209
  allvaluesobjects=await getAllRecords(COLLECTIONS.CUSTOM_VALUES);
189
- console.log("allvaluesobjects: ", allvaluesobjects);
190
210
  for (const value of allvaluesobjects) {
191
211
  valueToJobs[value._id]= value.jobIds;
192
212
  }
@@ -195,8 +215,12 @@ async function loadData(_$w) {
195
215
  allfields=await getAllRecords(COLLECTIONS.CUSTOM_FIELDS);
196
216
  allfields.push({_id:"Location",title:"Location"});
197
217
  }
218
+ } catch (error) {
219
+ console.error('Failed to load data:', error);
220
+ }
198
221
  }
199
222
  async function loadJobsRepeater(_$w) {
223
+ try {
200
224
  _$w(CAREERS_MULTI_BOXES_PAGE_CONSTS.JOBS_REPEATER).onItemReady(($item, itemData) => {
201
225
  $item(CAREERS_MULTI_BOXES_PAGE_CONSTS.JOBS_REPEATER_ITEM_TITLE).text = itemData.title;
202
226
  $item(CAREERS_MULTI_BOXES_PAGE_CONSTS.JOBS_REPEATER_ITEM_TITLE).onClick(async () => {
@@ -213,7 +237,10 @@ async function loadJobsRepeater(_$w) {
213
237
  _$w(CAREERS_MULTI_BOXES_PAGE_CONSTS.paginationTotalCountText).text = currentJobs.length.toString();
214
238
  updateTotalJobsCountText(_$w);
215
239
  handlePaginationButtons(_$w);
240
+ } catch (error) {
241
+ console.error('Failed to load jobs repeater:', error);
216
242
  }
243
+ }
217
244
 
218
245
  function updateTotalJobsCountText(_$w) {
219
246
  secondarySearchIsFilled? _$w(CAREERS_MULTI_BOXES_PAGE_CONSTS.TotalJobsCountText).text = `${currentSecondarySearchJobs.length} Jobs`:
@@ -341,30 +368,30 @@ async function loadJobsRepeater(_$w) {
341
368
  if(keyword) {
342
369
  finalFilteredJobs=currentJobs
343
370
  }
344
- let addedJobsIds=[]
371
+ let addedJobsIds=new Set();
345
372
  // AND across categories, OR within each category
346
373
  for (const [key, values] of selectedByField.entries()) {
347
374
  for(const job of finalFilteredJobs) {
348
375
  if(key==="Location"){
349
376
  //if it is location then we check if selecred values (which is an array) have job city text
350
377
  if(values.includes(job[JOBS_COLLECTION_FIELDS.CITY_TEXT])) {
351
- if(!addedJobsIds.includes(job._id)) {
378
+ if(!addedJobsIds.has(job._id)) {
352
379
  tempFilteredJobs.push(job);
353
- addedJobsIds.push(job._id);
380
+ addedJobsIds.add(job._id);
354
381
  }
355
382
  }
356
383
  }
357
384
  else{
358
385
  //if it is not location then we check if selecred values (which is an array) have one of the job values (whcih is also an array)
359
386
  if(job[JOBS_COLLECTION_FIELDS.MULTI_REF_JOBS_CUSTOM_VALUES].some(value=>values.includes(value._id))) {
360
- if(!addedJobsIds.includes(job._id)) {
387
+ if(!addedJobsIds.has(job._id)) {
361
388
  tempFilteredJobs.push(job);
362
- addedJobsIds.push(job._id);
389
+ addedJobsIds.add(job._id);
363
390
  }
364
391
  }
365
392
  }
366
393
  }
367
- addedJobsIds=[]
394
+ addedJobsIds.clear();
368
395
  finalFilteredJobs=tempFilteredJobs;
369
396
  tempFilteredJobs=[];
370
397
  }
@@ -387,11 +414,20 @@ async function loadJobsRepeater(_$w) {
387
414
  function handlePaginationButtons(_$w)
388
415
  {
389
416
  handlePageUrlParam();
417
+
390
418
  pagination.currentPage===1? _$w(CAREERS_MULTI_BOXES_PAGE_CONSTS.PAGE_BUTTON_PREVIOUS).disable():_$w(CAREERS_MULTI_BOXES_PAGE_CONSTS.PAGE_BUTTON_PREVIOUS).enable();
391
419
  if(secondarySearchIsFilled) {
420
+ if(currentSecondarySearchJobs.length===0) {
421
+ _$w(CAREERS_MULTI_BOXES_PAGE_CONSTS.PAGE_BUTTON_NEXT).disable();
422
+ return;
423
+ }
392
424
  pagination.currentPage>=Math.ceil(currentSecondarySearchJobs.length/pagination.pageSize)? _$w(CAREERS_MULTI_BOXES_PAGE_CONSTS.PAGE_BUTTON_NEXT).disable():_$w(CAREERS_MULTI_BOXES_PAGE_CONSTS.PAGE_BUTTON_NEXT).enable();
393
425
  }
394
426
  else {
427
+ if(currentJobs.length===0) {
428
+ _$w(CAREERS_MULTI_BOXES_PAGE_CONSTS.PAGE_BUTTON_NEXT).disable();
429
+ return;
430
+ }
395
431
  pagination.currentPage>=Math.ceil(currentJobs.length/pagination.pageSize)? _$w(CAREERS_MULTI_BOXES_PAGE_CONSTS.PAGE_BUTTON_NEXT).disable():_$w(CAREERS_MULTI_BOXES_PAGE_CONSTS.PAGE_BUTTON_NEXT).enable();
396
432
  }
397
433
  }
@@ -498,6 +534,7 @@ async function secondarySearch(_$w,query) {
498
534
  return allsecondarySearchJobs;
499
535
  }
500
536
  async function bindSearchInput(_$w) {
537
+ try {
501
538
  const primarySearchDebounced = debounce(async () => {
502
539
  const query = (_$w(CAREERS_MULTI_BOXES_PAGE_CONSTS.PRIMARY_SEARCH_INPUT).value || '').toLowerCase().trim();
503
540
  await primarySearch(_$w, query);
@@ -556,7 +593,10 @@ async function secondarySearch(_$w,query) {
556
593
  _$w(CAREERS_MULTI_BOXES_PAGE_CONSTS.RESULTS_CONTAINER).collapse();
557
594
  }
558
595
  });
596
+ } catch (error) {
597
+ console.error('Failed to bind search input:', error);
559
598
  }
599
+ }
560
600
 
561
601
  async function loadCategoriesListPrimarySearch(_$w) {
562
602
  _$w(CAREERS_MULTI_BOXES_PAGE_CONSTS.PRIMARY_SEARCH_MULTI_BOX).changeState("categoryResults");
@@ -23,7 +23,7 @@ function groupValuesByField(values, refKey) {
23
23
  };
24
24
 
25
25
  async function getAllRecords(collectionId) {
26
- let q = wixData.query(collectionId).include(JOBS_COLLECTION_FIELDS.MULTI_REF_JOBS_CUSTOM_VALUES)
26
+ const q = wixData.query(collectionId).include(JOBS_COLLECTION_FIELDS.MULTI_REF_JOBS_CUSTOM_VALUES)
27
27
 
28
28
 
29
29
  const items = [];
@@ -1,9 +1,40 @@
1
1
  const rewire = require('rewire');
2
2
  const MockJobBuilder = require('./mockJobBuilder');
3
- const { CAREERS_MULTI_BOXES_PAGE_CONSTS } = require('../backend/careersMultiBoxesPageIds');
3
+ const { CAREERS_MULTI_BOXES_PAGE_CONSTS, CATEGORY_CUSTOM_FIELD_ID_IN_CMS } = require('../backend/careersMultiBoxesPageIds');
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
+ };
4
29
 
5
30
  const careersMultiBoxesPage = rewire('../pages/careersMultiBoxesPage');
31
+
32
+ // Restore original require
33
+ Module.prototype.require = originalRequire;
34
+
6
35
  const secondarySearch = careersMultiBoxesPage.__get__('secondarySearch');
36
+ const primarySearch = careersMultiBoxesPage.__get__('primarySearch');
37
+ const loadCategoriesListPrimarySearch = careersMultiBoxesPage.__get__('loadCategoriesListPrimarySearch');
7
38
 
8
39
 
9
40
 
@@ -15,6 +46,7 @@ describe('secondarySearch function tests', () => {
15
46
  let mockPageButtonNext;
16
47
  let mockPageButtonPrevious;
17
48
  let mockTotalJobsCountText;
49
+ let mockJobsMultiStateBox;
18
50
 
19
51
  beforeEach(() => {
20
52
  mockJobsRepeater = { data: null };
@@ -29,6 +61,7 @@ describe('secondarySearch function tests', () => {
29
61
  disable: jest.fn()
30
62
  };
31
63
  mockTotalJobsCountText = { text: '' };
64
+ mockJobsMultiStateBox = { changeState: jest.fn() };
32
65
 
33
66
  mockW = jest.fn((selector) => {
34
67
  const mocks = {
@@ -37,7 +70,8 @@ describe('secondarySearch function tests', () => {
37
70
  [CAREERS_MULTI_BOXES_PAGE_CONSTS.paginationTotalCountText]: mockPaginationTotalCountText,
38
71
  [CAREERS_MULTI_BOXES_PAGE_CONSTS.PAGE_BUTTON_NEXT]: mockPageButtonNext,
39
72
  [CAREERS_MULTI_BOXES_PAGE_CONSTS.PAGE_BUTTON_PREVIOUS]: mockPageButtonPrevious,
40
- [CAREERS_MULTI_BOXES_PAGE_CONSTS.TotalJobsCountText]: mockTotalJobsCountText
73
+ [CAREERS_MULTI_BOXES_PAGE_CONSTS.TotalJobsCountText]: mockTotalJobsCountText,
74
+ [CAREERS_MULTI_BOXES_PAGE_CONSTS.JOBS_MULTI_STATE_BOX]: mockJobsMultiStateBox
41
75
  };
42
76
  return mocks[selector] || {
43
77
  data: null,
@@ -47,7 +81,8 @@ describe('secondarySearch function tests', () => {
47
81
  onChange: jest.fn(),
48
82
  onInput: jest.fn(),
49
83
  enable: jest.fn(),
50
- disable: jest.fn()
84
+ disable: jest.fn(),
85
+ changeState: jest.fn()
51
86
  };
52
87
  });
53
88
  });
@@ -57,7 +92,7 @@ describe('secondarySearch function tests', () => {
57
92
  careersMultiBoxesPage.__set__('currentJobs', []);
58
93
  });
59
94
 
60
- it('should return count > 0 when searching for existing job title', () => {
95
+ it('should return count > 0 when searching for existing job title', async () => {
61
96
 
62
97
 
63
98
  let mockJobs = MockJobBuilder.createMultiple(11, (builder, index) => {
@@ -69,27 +104,26 @@ describe('secondarySearch function tests', () => {
69
104
 
70
105
  careersMultiBoxesPage.__set__('currentJobs', mockJobs);
71
106
 
72
- const result = secondarySearch(mockW, 'product');
107
+ const result = await secondarySearch(mockW, 'product');
73
108
 
74
109
  expect(result.length).toBe(11);
75
- expect(mockTotalJobsCountText.text).toContain('11 Jobs');
110
+ expect(mockTotalJobsCountText.text).toContain('11');
76
111
  expect(mockPaginationCurrentText.text).toBe('10');
77
112
  expect(mockPaginationTotalCountText.text).toBe('11');
78
113
  expect(mockPageButtonNext.enable).toHaveBeenCalled();
79
114
  expect(mockPageButtonPrevious.disable).toHaveBeenCalled();
80
115
  });
81
116
 
82
- it('should return 0 when searching for non-existing job title', () => {
117
+ it('should return 0 when searching for non-existing job title', async () => {
83
118
  let mockJobs = MockJobBuilder.createMultiple(11, (builder, index) => {
84
119
  builder.withTitle(`random job ${index}`);
85
120
  });
86
121
  careersMultiBoxesPage.__set__('currentJobs', mockJobs);
87
122
 
88
- const result = secondarySearch(mockW, 'unicorn hunter');
123
+ const result = await secondarySearch(mockW, 'unicorn hunter');
89
124
 
90
125
  expect(result.length).toBe(0);
91
126
  expect(mockTotalJobsCountText.text).toContain('0 Jobs');
92
- expect(mockPaginationCurrentText.text).toBe('0');
93
127
  expect(mockPaginationTotalCountText.text).toBe('0');
94
128
  expect(mockPageButtonNext.disable).toHaveBeenCalled();
95
129
  expect(mockPageButtonPrevious.disable).toHaveBeenCalled();
@@ -98,3 +132,75 @@ describe('secondarySearch function tests', () => {
98
132
 
99
133
  });
100
134
 
135
+
136
+ describe('primarySearch function tests', () => {
137
+ let mockW;
138
+ let mockprimarySearcJobResult;
139
+ let mockprimarySearchMultiBox;
140
+ let mockCategoryResultsRepeater;
141
+
142
+ beforeEach(() => {
143
+ mockprimarySearcJobResult = { data: null };
144
+ mockprimarySearchMultiBox = { changeState: jest.fn() };
145
+ mockCategoryResultsRepeater = { data: null };
146
+
147
+ mockW = jest.fn((selector) => {
148
+ const mocks = {
149
+ [CAREERS_MULTI_BOXES_PAGE_CONSTS.JOB_RESULTS_REPEATER]: mockprimarySearcJobResult,
150
+ [CAREERS_MULTI_BOXES_PAGE_CONSTS.PRIMARY_SEARCH_MULTI_BOX]: mockprimarySearchMultiBox,
151
+ [CAREERS_MULTI_BOXES_PAGE_CONSTS.CATEGORY_RESULTS_REPEATER]: mockCategoryResultsRepeater
152
+ };
153
+ return mocks[selector]
154
+ });
155
+ });
156
+
157
+ afterEach(() => {
158
+ jest.clearAllMocks();
159
+ careersMultiBoxesPage.__set__('currentJobs', []);
160
+ });
161
+
162
+ it('should show job results for existing job title', async () => {
163
+ let mockJobs = MockJobBuilder.createMultiple(11, (builder, index) => {
164
+ builder.withTitle(`Product Manager ${index}`);
165
+ });
166
+ careersMultiBoxesPage.__set__('alljobs', mockJobs);
167
+
168
+ await primarySearch(mockW, 'product');
169
+
170
+ expect(mockprimarySearchMultiBox.changeState).toHaveBeenCalledWith('jobResults');
171
+ expect(mockprimarySearcJobResult.data).toHaveLength(11);
172
+ expect(mockprimarySearcJobResult.data).toEqual(mockJobs);
173
+ });
174
+
175
+ it('should show no results for non-existing job title', async () => {
176
+ let mockJobs = MockJobBuilder.createMultiple(11, (builder, index) => {
177
+ builder.withTitle(`Product Manager ${index}`);
178
+ });
179
+ careersMultiBoxesPage.__set__('alljobs', mockJobs);
180
+
181
+ await primarySearch(mockW, 'unicorn hunter');
182
+
183
+ expect(mockprimarySearchMultiBox.changeState).toHaveBeenCalledWith('noResults');
184
+ expect(mockprimarySearcJobResult.data).toBeNull();
185
+ });
186
+
187
+ it('should fill category repeater when clicking on empty primary search input', async () => {
188
+ const mockCategoryValues = [
189
+ { _id: 'cat1', title: 'Engineering', customField: CATEGORY_CUSTOM_FIELD_ID_IN_CMS, totalJobs: 5 },
190
+ { _id: 'cat2', title: 'Marketing', customField: CATEGORY_CUSTOM_FIELD_ID_IN_CMS, totalJobs: 3 },
191
+ { _id: 'cat3', title: 'Sales', customField: CATEGORY_CUSTOM_FIELD_ID_IN_CMS, totalJobs: 7 }
192
+ ];
193
+
194
+ careersMultiBoxesPage.__set__('allvaluesobjects', mockCategoryValues);
195
+
196
+ await loadCategoriesListPrimarySearch(mockW);
197
+
198
+ expect(mockprimarySearchMultiBox.changeState).toHaveBeenCalledWith('categoryResults');
199
+ expect(mockCategoryResultsRepeater.data).toHaveLength(3);
200
+ expect(mockCategoryResultsRepeater.data[0].title).toContain('Engineering (5)');
201
+ expect(mockCategoryResultsRepeater.data[1].title).toContain('Marketing (3)');
202
+ expect(mockCategoryResultsRepeater.data[2].title).toContain('Sales (7)');
203
+ });
204
+
205
+ });
206
+