sr-npm 1.7.401 → 1.7.403
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/backend/collectionConsts.js +11 -1
- package/backend/consts.js +1 -1
- package/backend/data.js +29 -6
- package/backend/fetchPositionsFromSRAPI.js +29 -12
- package/backend/secretsData.js +10 -2
- package/package.json +1 -1
- package/tests/fetchPositionsFromSRApiTest.spec.js +4 -28
- package/tests/testsUtils.js +1 -11
|
@@ -3,6 +3,8 @@ const COLLECTIONS = {
|
|
|
3
3
|
CITIES: 'cities',
|
|
4
4
|
JOBS: 'Jobs',
|
|
5
5
|
COMPANY_ID: 'CompanyId',
|
|
6
|
+
API_KEY: 'ApiKey',
|
|
7
|
+
TEMPLATE_TYPE: 'templateType',
|
|
6
8
|
}
|
|
7
9
|
const JOBS_COLLECTION_FIELDS = {
|
|
8
10
|
LOCATION: 'location',
|
|
@@ -18,6 +20,7 @@ const JOBS_COLLECTION_FIELDS = {
|
|
|
18
20
|
CITY_TEXT: 'cityText',
|
|
19
21
|
IMAGE: 'image',
|
|
20
22
|
APPLY_LINK: 'applyLink',
|
|
23
|
+
REFER_FRIEND_LINK: 'referFriendLink',
|
|
21
24
|
}
|
|
22
25
|
const AMOUNT_OF_JOBS_PER_DEPARTMENT_COLLECTION_FIELDS = {
|
|
23
26
|
TITLE: 'title',
|
|
@@ -54,7 +57,8 @@ const COLLECTIONS_FIELDS = {
|
|
|
54
57
|
{key:'remote', type: 'BOOLEAN'},
|
|
55
58
|
{key:'jobDescription', type: 'OBJECT'},
|
|
56
59
|
{key:'cityText', type: 'TEXT'},
|
|
57
|
-
{key:'applyLink', type: 'URL'},
|
|
60
|
+
{key:'applyLink', type: 'URL'},
|
|
61
|
+
{key:'referFriendLink', type: 'URL'},
|
|
58
62
|
{key:'departmentref', type: 'REFERENCE', typeMetadata: { reference: { referencedCollectionId: COLLECTIONS.AMOUNT_OF_JOBS_PER_DEPARTMENT } } },
|
|
59
63
|
{key:'city', type: 'REFERENCE', typeMetadata: { reference: { referencedCollectionId: COLLECTIONS.CITIES } } },
|
|
60
64
|
{ key: 'image', type: 'IMAGE' },
|
|
@@ -62,6 +66,12 @@ const COLLECTIONS_FIELDS = {
|
|
|
62
66
|
COMPANY_ID: [
|
|
63
67
|
{key:'companyId', type: 'TEXT'},
|
|
64
68
|
],
|
|
69
|
+
API_KEY: [
|
|
70
|
+
{key:'token', type: 'TEXT'},
|
|
71
|
+
],
|
|
72
|
+
TEMPLATE_TYPE: [
|
|
73
|
+
{key:'templateType', type: 'TEXT'},
|
|
74
|
+
],
|
|
65
75
|
};
|
|
66
76
|
|
|
67
77
|
|
package/backend/consts.js
CHANGED
package/backend/data.js
CHANGED
|
@@ -4,7 +4,7 @@ const { createCollectionIfMissing } = require('@hisense-staging/velo-npm/backend
|
|
|
4
4
|
const { COLLECTIONS, COLLECTIONS_FIELDS,JOBS_COLLECTION_FIELDS } = require('./collectionConsts');
|
|
5
5
|
const { chunkedBulkOperation, countJobsPerGivenField, fillCityLocationAndLocationAddress ,prepareToSaveArray,normalizeCityName} = require('./utils');
|
|
6
6
|
const { getAllPositions } = require('./queries');
|
|
7
|
-
const { getCompanyId } = require('./secretsData');
|
|
7
|
+
const { getCompanyId, getSmartToken } = require('./secretsData');
|
|
8
8
|
|
|
9
9
|
function validatePosition(position) {
|
|
10
10
|
if (!position.id) {
|
|
@@ -120,7 +120,7 @@ async function saveJobsDescriptionsAndLocationApplyUrlToCMS() {
|
|
|
120
120
|
try {
|
|
121
121
|
const jobDetails = await fetchJobDescription(job._id);
|
|
122
122
|
const jobLocation = fetchJobLocation(jobDetails);
|
|
123
|
-
const applyLink =
|
|
123
|
+
const {applyLink , referFriendLink} = fetchApplyAndReferFriendLink(jobDetails);
|
|
124
124
|
|
|
125
125
|
|
|
126
126
|
const updatedJob = {
|
|
@@ -128,6 +128,7 @@ async function saveJobsDescriptionsAndLocationApplyUrlToCMS() {
|
|
|
128
128
|
locationAddress: jobLocation,
|
|
129
129
|
jobDescription: jobDetails.jobAd.sections,
|
|
130
130
|
applyLink: applyLink,
|
|
131
|
+
referFriendLink: referFriendLink,
|
|
131
132
|
};
|
|
132
133
|
await wixData.update(COLLECTIONS.JOBS, updatedJob);
|
|
133
134
|
return { success: true, jobId: job._id, title: job.title };
|
|
@@ -258,8 +259,8 @@ async function referenceJobsToField({ referenceField, sourceCollection, jobField
|
|
|
258
259
|
return { success: true, updated: jobsToUpdate.length };
|
|
259
260
|
}
|
|
260
261
|
|
|
261
|
-
function
|
|
262
|
-
return jobDetails.applyUrl;
|
|
262
|
+
function fetchApplyAndReferFriendLink(jobDetails) {
|
|
263
|
+
return {applyLink: jobDetails.applyUrl, referFriendLink: jobDetails.referralUrl};
|
|
263
264
|
}
|
|
264
265
|
|
|
265
266
|
function fetchJobLocation(jobDetails) {
|
|
@@ -285,7 +286,27 @@ function fetchJobLocation(jobDetails) {
|
|
|
285
286
|
return jobLocation;
|
|
286
287
|
}
|
|
287
288
|
|
|
288
|
-
|
|
289
|
+
async function createApiKeyCollectionAndFillIt() {
|
|
290
|
+
console.log("Creating ApiKey collection and filling it with the smart token");
|
|
291
|
+
await createCollectionIfMissing(COLLECTIONS.API_KEY, COLLECTIONS_FIELDS.API_KEY,null,'singleItem');
|
|
292
|
+
console.log("Getting the smart token ");
|
|
293
|
+
const token = await getSmartToken();
|
|
294
|
+
console.log("token is : ", token);
|
|
295
|
+
console.log("Inserting the smart token into the ApiKey collection");
|
|
296
|
+
try {
|
|
297
|
+
await wixData.insert(COLLECTIONS.API_KEY, {
|
|
298
|
+
token: token.value
|
|
299
|
+
});
|
|
300
|
+
console.log("Smart token inserted into the ApiKey collection");
|
|
301
|
+
} catch (error) {
|
|
302
|
+
if (error.message.includes("WDE0074: An item with _id [SINGLE_ITEM_ID] already exists")) {
|
|
303
|
+
console.log("Smart token already exists in the ApiKey collection");
|
|
304
|
+
}
|
|
305
|
+
else {
|
|
306
|
+
throw error;
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
}
|
|
289
310
|
|
|
290
311
|
|
|
291
312
|
async function createCompanyIdCollectionAndFillIt() {
|
|
@@ -338,9 +359,11 @@ async function referenceJobs() {
|
|
|
338
359
|
console.log("finished referencing jobs");
|
|
339
360
|
}
|
|
340
361
|
|
|
341
|
-
async function syncJobsFast() {
|
|
362
|
+
async function syncJobsFast(templateType) {
|
|
363
|
+
console.log("templateType is : ", templateType);
|
|
342
364
|
console.log("Syncing jobs fast");
|
|
343
365
|
await createCompanyIdCollectionAndFillIt();
|
|
366
|
+
await createApiKeyCollectionAndFillIt();
|
|
344
367
|
await createCollections();
|
|
345
368
|
await clearCollections();
|
|
346
369
|
console.log("saving jobs data to CMS");
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
const { fetch } = require('wix-fetch');
|
|
2
2
|
const { items: wixData } = require('@wix/data');
|
|
3
3
|
const { COLLECTIONS } = require('./collectionConsts');
|
|
4
|
-
|
|
4
|
+
|
|
5
|
+
async function makeSmartRecruitersRequest(path,smartToken) {
|
|
5
6
|
const baseUrl = 'https://api.smartrecruiters.com';
|
|
6
7
|
const fullUrl = `${baseUrl}${path}`;
|
|
7
8
|
|
|
@@ -11,7 +12,8 @@ async function makeSmartRecruitersRequest(path) {
|
|
|
11
12
|
headers: {
|
|
12
13
|
'Accept-Language': 'en',
|
|
13
14
|
'accept': 'application/json',
|
|
14
|
-
'Cookie': 'AWSALB=GYltFw3fLKortMxHR5vIOT1CuUROyhWNIX/qL8ZnPl1/8mhOcnIsBKYslzmNJPEzSy/jvNbO+6tXpH8yqcpQJagYt57MhbKlLqTSzoNq1G/w7TjOxPGR3UTdXW0d; AWSALBCORS=GYltFw3fLKortMxHR5vIOT1CuUROyhWNIX/qL8ZnPl1/8mhOcnIsBKYslzmNJPEzSy/jvNbO+6tXpH8yqcpQJagYt57MhbKlLqTSzoNq1G/w7TjOxPGR3UTdXW0d'
|
|
15
|
+
'Cookie': 'AWSALB=GYltFw3fLKortMxHR5vIOT1CuUROyhWNIX/qL8ZnPl1/8mhOcnIsBKYslzmNJPEzSy/jvNbO+6tXpH8yqcpQJagYt57MhbKlLqTSzoNq1G/w7TjOxPGR3UTdXW0d; AWSALBCORS=GYltFw3fLKortMxHR5vIOT1CuUROyhWNIX/qL8ZnPl1/8mhOcnIsBKYslzmNJPEzSy/jvNbO+6tXpH8yqcpQJagYt57MhbKlLqTSzoNq1G/w7TjOxPGR3UTdXW0d',
|
|
16
|
+
'x-smarttoken': smartToken
|
|
15
17
|
}
|
|
16
18
|
});
|
|
17
19
|
|
|
@@ -27,16 +29,14 @@ async function makeSmartRecruitersRequest(path) {
|
|
|
27
29
|
}
|
|
28
30
|
}
|
|
29
31
|
|
|
30
|
-
async function fetchPositionsFromSRAPI(
|
|
32
|
+
async function fetchPositionsFromSRAPI() {
|
|
31
33
|
let allPositions = [];
|
|
32
34
|
let totalFound = 0;
|
|
33
35
|
let page = 0;
|
|
34
36
|
const MAX_PAGES = 30 // Safety limit to prevent infinite loops
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
companyId = await getCompanyIdFromCMS();
|
|
39
|
-
}
|
|
37
|
+
const companyId = await getCompanyIdFromCMS();
|
|
38
|
+
const templateType = await getTemplateTypeFromCMS();
|
|
39
|
+
const smartToken = templateType==='INTERNAL' ? await getSmartTokenFromCMS():undefined;
|
|
40
40
|
console.log('Starting to fetch all positions with pagination...');
|
|
41
41
|
let offset=0;
|
|
42
42
|
|
|
@@ -45,10 +45,10 @@ async function fetchPositionsFromSRAPI(companyID=undefined) {
|
|
|
45
45
|
page++;
|
|
46
46
|
|
|
47
47
|
// Build the API path - first request has no page parameter, subsequent use nextPageId
|
|
48
|
-
const apiPath = `/v1/companies/${companyId}/postings?offset=${offset}`;
|
|
48
|
+
const apiPath = `/v1/companies/${companyId}/postings?offset=${offset}&destination=${templateType}`;
|
|
49
49
|
|
|
50
50
|
console.log(`Fetching page ${page} with path: ${apiPath}`);
|
|
51
|
-
const response = await makeSmartRecruitersRequest(apiPath);
|
|
51
|
+
const response = await makeSmartRecruitersRequest(apiPath,smartToken);
|
|
52
52
|
|
|
53
53
|
// Add positions from this page to our collection
|
|
54
54
|
if (response.content && Array.isArray(response.content)) {
|
|
@@ -111,10 +111,27 @@ async function getCompanyIdFromCMS() {
|
|
|
111
111
|
}
|
|
112
112
|
}
|
|
113
113
|
|
|
114
|
+
async function getSmartTokenFromCMS() {
|
|
115
|
+
const result = await wixData.query(COLLECTIONS.API_KEY).limit(1).find();
|
|
116
|
+
if (result.items.length > 0) {
|
|
117
|
+
return result.items[0].token;
|
|
118
|
+
} else {
|
|
119
|
+
throw new Error('[getSmartTokenFromCMS], No smarttoken found');
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
async function getTemplateTypeFromCMS() {
|
|
123
|
+
console.log("COLLECTIONS.TEMPLATE_TYPE is ",COLLECTIONS.TEMPLATE_TYPE)
|
|
124
|
+
const result = await wixData.query(COLLECTIONS.TEMPLATE_TYPE).limit(1).find();
|
|
125
|
+
if (result.items.length > 0) {
|
|
126
|
+
return result.items[0].templateType;
|
|
127
|
+
} else {
|
|
128
|
+
throw new Error('[getTemplateTypeFromCMS], No templateType found');
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
|
|
114
132
|
|
|
115
133
|
module.exports = {
|
|
116
134
|
fetchPositionsFromSRAPI,
|
|
117
135
|
fetchJobDescription,
|
|
118
|
-
getCompanyIdFromCMS
|
|
119
|
-
makeSmartRecruitersRequest
|
|
136
|
+
getCompanyIdFromCMS
|
|
120
137
|
};
|
package/backend/secretsData.js
CHANGED
|
@@ -2,7 +2,14 @@ const { secrets } = require("@wix/secrets");
|
|
|
2
2
|
const { auth } = require('@wix/essentials');
|
|
3
3
|
|
|
4
4
|
const getSecretValue = auth.elevate(secrets.getSecretValue);
|
|
5
|
-
|
|
5
|
+
|
|
6
|
+
function getSmartToken() {
|
|
7
|
+
return getSecretValue("x-smarttoken")
|
|
8
|
+
.then((secret) => {
|
|
9
|
+
return secret;
|
|
10
|
+
})
|
|
11
|
+
}
|
|
12
|
+
|
|
6
13
|
function getCompanyId() {
|
|
7
14
|
return getSecretValue("companyID")
|
|
8
15
|
.then((secret) => {
|
|
@@ -10,5 +17,6 @@ const getSecretValue = auth.elevate(secrets.getSecretValue);
|
|
|
10
17
|
})
|
|
11
18
|
}
|
|
12
19
|
module.exports = {
|
|
13
|
-
getCompanyId
|
|
20
|
+
getCompanyId,
|
|
21
|
+
getSmartToken
|
|
14
22
|
};
|
package/package.json
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
const { executeApiRequest } = require('tests-utils');
|
|
2
|
-
const { getRandomPosition
|
|
2
|
+
const { getRandomPosition } = require('./testsUtils');
|
|
3
3
|
|
|
4
4
|
describe('Job details fetch from SR API Tests', () => {
|
|
5
5
|
|
|
@@ -30,30 +30,6 @@ describe('Job details fetch from SR API Tests', () => {
|
|
|
30
30
|
expect(jobFetchResponse.data.result.applyUrl.length).toBeGreaterThan(0);
|
|
31
31
|
expect(jobFetchResponse.data.result.location).toBeDefined();
|
|
32
32
|
});
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
test('should throw error if invalid companyId is found', async () => {
|
|
37
|
-
const requestBody = `fetchPositionsFromSRAPI('invalid_company_id');`;
|
|
38
|
-
executeRequestAndTest(requestBody)
|
|
39
|
-
});
|
|
40
|
-
|
|
41
|
-
test('should throw error when a bad URL is used', async () => {
|
|
42
|
-
const requestBody = `makeSmartRecruitersRequest('/v1/error/companyId/postings');`;
|
|
43
|
-
executeRequestAndTest(requestBody)
|
|
44
|
-
});
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
});
|
|
49
|
-
|
|
50
|
-
describe('fetchJobDescription error handling', () => {
|
|
51
|
-
test('should throw error if invalid jobId is found', async () => {
|
|
52
|
-
const requestBody = `fetchJobDescription('invalid_job_id');`;
|
|
53
|
-
executeRequestAndTest(requestBody)
|
|
54
|
-
});
|
|
55
|
-
test('should throw error when given a valid jobId but no jobAdId is found', async () => {
|
|
56
|
-
const requestBody = `fetchJobDescription('1234567890');`;
|
|
57
|
-
executeRequestAndTest(requestBody)
|
|
58
|
-
});
|
|
59
|
-
});
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
});
|
package/tests/testsUtils.js
CHANGED
|
@@ -1,17 +1,7 @@
|
|
|
1
|
-
const { executeApiRequest } = require('tests-utils');
|
|
2
|
-
|
|
3
1
|
function getRandomPosition(positions) {
|
|
4
2
|
return positions[Math.floor(Math.random() * positions.length)];
|
|
5
3
|
}
|
|
6
|
-
async function executeRequestAndTest(requestBody) {
|
|
7
|
-
try{
|
|
8
|
-
response = await executeApiRequest(requestBody);
|
|
9
|
-
expect(response.status).not.toBe(500);
|
|
10
|
-
}catch(error){
|
|
11
|
-
expect(error.message).toBe('Request failed with status code 500');
|
|
12
|
-
}
|
|
13
|
-
}
|
|
14
4
|
|
|
15
5
|
module.exports = {
|
|
16
|
-
getRandomPosition
|
|
6
|
+
getRandomPosition
|
|
17
7
|
}
|