Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

234 multiple locations in job offer #338

Closed
wants to merge 9 commits into from
Closed
21 changes: 12 additions & 9 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 7 additions & 5 deletions src/api/middleware/validators/offer.js
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,6 @@ export const create = useExpressValidators([
.custom(publishEndDateAfterPublishDate)
.custom(publishEndDateLimit),


body("jobMinDuration", ValidationReasons.DEFAULT)
.exists().withMessage(ValidationReasons.REQUIRED).bail()
.isInt().withMessage(ValidationReasons.INT),
Expand Down Expand Up @@ -161,8 +160,9 @@ export const create = useExpressValidators([

body("location", ValidationReasons.DEFAULT)
.exists().withMessage(ValidationReasons.REQUIRED).bail()
.isString().withMessage(ValidationReasons.STRING)
.trim(),
.customSanitizer(ensureArray)
.isArray({ min: OfferConstants.locations.min_length, max: OfferConstants.locations.max_length })
.withMessage(ValidationReasons.ARRAY_SIZE(OfferConstants.locations.min_length, OfferConstants.locations.max_length)),

// TODO: Figure out how to handle this field
// We should probably only receive the array part and inject the type that PointSchema requires in a custom sanitizer
Expand Down Expand Up @@ -410,8 +410,10 @@ export const edit = useExpressValidators([

body("location", ValidationReasons.DEFAULT)
.optional()
.isString().withMessage(ValidationReasons.STRING)
.trim(),
.customSanitizer(ensureArray)
.isArray({ min: OfferConstants.locations.min_length, max: OfferConstants.locations.max_length })
.withMessage(ValidationReasons.ARRAY_SIZE(OfferConstants.locations.min_length, OfferConstants.locations.max_length)),

body("requirements", ValidationReasons.DEFAULT)
.optional()
.isArray({ min: OfferConstants.requirements.min_length })
Expand Down
9 changes: 8 additions & 1 deletion src/models/Offer.js
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,14 @@ const OfferSchema = new Schema({
},
ownerName: { type: String, required: true },
ownerLogo: { type: String, required: true, validate: (val) => validImageURL(val) },
location: { type: String, required: true },
location: {
type: [String],
required: true,
validate: [
(val) => lengthBetweenValidator(val, OfferConstants.locations.min_length, OfferConstants.locations.max_length),
`There must be between ${OfferConstants.locations.min_length} and ${OfferConstants.locations.max_length} locations`,
],
},
coordinates: { type: PointSchema, required: false },
applyURL: { type: String, validate: (val) => validApplyURL(val) },
});
Expand Down
6 changes: 5 additions & 1 deletion src/models/constants/Offer.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,5 +32,9 @@ export default Object.freeze({
"jobType",
"ownerName",
"location",
]
],
locations: {
min_length: 1,
max_length: 20,
}
});
38 changes: 19 additions & 19 deletions test/end-to-end/offer.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import {
} from "../../src/models/constants/TimeConstants";
import OfferService from "../../src/services/offer";
import EmailService from "../../src/lib/emailService";
import { concurrentOffersNotExceeded } from "../../src/api/middleware/validators/validatorUtils";
import { concurrentOffersNotExceeded, ensureArray } from "../../src/api/middleware/validators/validatorUtils";
import { OFFER_DISABLED_NOTIFICATION } from "../../src/email-templates/companyOfferDisabled";
import base64url from "base64url";

Expand All @@ -36,7 +36,7 @@ describe("Offer endpoint tests", () => {
jobType: "SUMMER INTERNSHIP",
fields: ["DEVOPS", "BACKEND", "OTHER"],
technologies: ["React", "CSS"],
location: "Testing Street, Test City, 123",
location: ["Porto"],
isHidden: false,
isArchived: false,
requirements: ["The candidate must be tested", "Fluent in testJS"],
Expand Down Expand Up @@ -124,7 +124,7 @@ describe("Offer endpoint tests", () => {
expect(res.status).toBe(HTTPStatus.OK);
expect(res.body).toHaveProperty("title", offer.title);
expect(res.body).toHaveProperty("description", offer.description);
expect(res.body).toHaveProperty("location", offer.location);
expect(res.body).toHaveProperty("location", ensureArray(offer.location));
});

test("should create offer if logged in to company account", async () => {
Expand All @@ -143,7 +143,7 @@ describe("Offer endpoint tests", () => {
expect(res.status).toBe(HTTPStatus.OK);
expect(res.body).toHaveProperty("title", offer.title);
expect(res.body).toHaveProperty("description", offer.description);
expect(res.body).toHaveProperty("location", offer.location);
expect(res.body).toHaveProperty("location", ensureArray(offer.location));
expect(res.body).toHaveProperty("owner", test_company._id.toString());
expect(res.body).toHaveProperty("ownerName", test_company.name);
expect(res.body).toHaveProperty("ownerLogo", test_company.logo);
Expand Down Expand Up @@ -202,7 +202,7 @@ describe("Offer endpoint tests", () => {
expect(res.status).toBe(HTTPStatus.OK);
expect(res.body).toHaveProperty("title", offer.title);
expect(res.body).toHaveProperty("description", offer.description);
expect(res.body).toHaveProperty("location", offer.location);
expect(res.body).toHaveProperty("location", ensureArray(offer.location));
});
});
});
Expand Down Expand Up @@ -303,7 +303,7 @@ describe("Offer endpoint tests", () => {
describe("location", () => {
const FieldValidatorTester = BodyValidatorTester("location");
FieldValidatorTester.isRequired();
FieldValidatorTester.mustBeString();
FieldValidatorTester.mustBeArrayBetween(OfferConstants.locations.min_length, OfferConstants.locations.max_length);
});

describe("requirements", () => {
Expand Down Expand Up @@ -377,7 +377,7 @@ describe("Offer endpoint tests", () => {
// However, no matter what I tried, I couldn't get it to work :upside_down_face:
expect(created_offer).toHaveProperty("title", offer.title);
expect(created_offer).toHaveProperty("description", offer.description);
expect(created_offer).toHaveProperty("location", offer.location);
expect(created_offer).toHaveProperty("location", ensureArray(offer.location));
expect(created_offer).toHaveProperty("ownerName", test_company.name);
expect(created_offer).toHaveProperty("ownerLogo", test_company.logo);
});
Expand Down Expand Up @@ -485,7 +485,7 @@ describe("Offer endpoint tests", () => {
expect(res.status).toBe(HTTPStatus.OK);
expect(res.body).toHaveProperty("title", offer_params.title);
expect(res.body).toHaveProperty("description", offer_params.description);
expect(res.body).toHaveProperty("location", offer_params.location);
expect(res.body).toHaveProperty("location", ensureArray(offer_params.location));
expect(res.body).toHaveProperty("ownerName", test_company.name);
expect(res.body).toHaveProperty("ownerLogo", test_company.logo);
});
Expand Down Expand Up @@ -657,7 +657,7 @@ describe("Offer endpoint tests", () => {
owner: test_company._id,
ownerName: test_company.name,
ownerLogo: test_company.logo,
location: "Testing Street, Test City, 123",
location: ["Porto", "Lisboa", "NI"],
requirements: ["The candidate must be tested", "Fluent in testJS"],
};

Expand All @@ -673,7 +673,7 @@ describe("Offer endpoint tests", () => {
expect(created_offer).toBeDefined();
expect(created_offer).toHaveProperty("title", offer.title);
expect(created_offer).toHaveProperty("description", offer.description);
expect(created_offer).toHaveProperty("location", offer.location);
expect(created_offer).toHaveProperty("location", ensureArray(offer.location));
expect(created_offer).toHaveProperty("publishDate");
expect(created_offer).toHaveProperty("ownerName", test_company.name);
expect(created_offer).toHaveProperty("ownerLogo", test_company.logo);
Expand Down Expand Up @@ -1850,27 +1850,27 @@ describe("Offer endpoint tests", () => {
portoFrontend = {
...test_offer,
title: "This offer is from Porto",
location: "Porto",
location: ["Porto"],
jobType: "FULL-TIME",
fields: ["FRONTEND", "OTHER"],
jobMinDuration: 3,
jobMaxDuration: 6
};
portoBackend = {
...test_offer,
location: "Porto",
location: ["Porto"],
fields: ["BACKEND", "OTHER"],
jobMinDuration: 2,
jobMaxDuration: 4
};
lisboaBackend = {
...test_offer,
location: "Lisboa",
location: ["Lisboa"],
fields: ["BACKEND", "DEVOPS"]
};
niaefeupOffer = {
...test_offer,
location: "FEUP",
location: ["FEUP"],
fields: ["BLOCKCHAIN", "OTHER"],
ownerName: "NIAEFEUP"
};
Expand Down Expand Up @@ -2184,7 +2184,7 @@ describe("Offer endpoint tests", () => {
const worstScore = {
...test_offer,
title: "This offer is from Braga",
location: "Porto",
location: ["Porto"],
"publishDate": (new Date(Date.now() - (DAY_TO_MS))).toISOString(),
"publishEndDate": (new Date(Date.now() + (DAY_TO_MS))).toISOString()
};
Expand Down Expand Up @@ -2694,7 +2694,7 @@ describe("Offer endpoint tests", () => {
publishEndDate: "2019-11-29T00:00:00.000Z",
description: "Ability to have an incredible job",
jobType: "OTHER",
location: "Aveiro",
location: ["Aveiro"],
vacancies: 1,
ownerName: "Awesome Company",
});
Expand Down Expand Up @@ -2902,7 +2902,7 @@ describe("Offer endpoint tests", () => {
publishEndDate: "2019-11-29T00:00:00.000Z",
description: "Ability to have an incredible job",
jobType: "OTHER",
location: "Aveiro",
location: ["Aveiro"],
ownerName: "Awesome Company",
vacancies: 3,
});
Expand Down Expand Up @@ -3780,7 +3780,7 @@ describe("Offer endpoint tests", () => {

describe("location", () => {
const FieldValidatorTester = BodyValidatorTester("location");
FieldValidatorTester.mustBeString();
FieldValidatorTester.mustBeArrayBetween(OfferConstants.locations.min_length, OfferConstants.locations.max_length);
});

describe("isHidden", () => {
Expand Down Expand Up @@ -3910,7 +3910,7 @@ describe("Offer endpoint tests", () => {
"title": "This is a new title",
"description": "This is a new description",
"jobMinDuration": valid_test_offer_1.jobMinDuration - 1,
"location": "Porto",
"location": ["Porto"],
"technologies": ["CSS"]
};
const res = await test_agent.post(`/offers/edit/${valid_test_offer_2._id}`)
Expand Down
Loading
Loading