Currently, I am in the process of developing a social media app and working on integrating a search feature to enable users to find friends. The code I have below seems to be functional at times but not consistent (quite frustrating!) The issue seems to stem from the asynchronous nature of JavaScript. I tried addressing this by using a 'then' function for the second search. Basically, the code should first search based on users' first names, then their last names, push the results into an array called users, flatten it out, extract unique user objects, and finally pass them to handlebars for display. The problem appears to arise with tests that involve more than one word where sometimes the second word is searched for and other times not:
- The search should return results for each word entered
- The search should not be affected by non-alphanumeric characters
Controller
const User = require("../models/user");
const SearchController = {
Index: (req, res) => {
const users = [];
User.find().then((user) => {
users.push(user);
const merged = [].concat.apply([], users);
const uniqueArray = merged.filter((value, index) => {
const _value = JSON.stringify(value);
return (
index ===
merged.findIndex((obj) => {
return JSON.stringify(obj) === _value;
})
);
});
res.render("search/index", { users: uniqueArray });
});
},
Create: (req, res) => {
const searchArray = req.body.message.replace(/[\W_]+/g, " ").split(/[ ,]+/);
const users = [];
searchArray.forEach((name) => {
User.find({
firstName: { $regex: name, $options: "i" },
// lastName: { $regex: name, $options: "i" },
}).then((user) => {
users.push(user);
User.find({
// firstName: { $regex: name, $options: "i" },
lastName: { $regex: name, $options: "i" },
}).then((user) => {
users.push(user);
const merged = [].concat.apply([], users);
const uniqueArray = merged.filter((value, index) => {
const _value = JSON.stringify(value);
return (
index ===
merged.findIndex((obj) => {
return JSON.stringify(obj) === _value;
})
);
});
res.render("search/index", { users: uniqueArray });
});
});
});
},
};
module.exports = SearchController;
Cypress Tests
describe("Searching users", () => {
beforeEach(() => {
cy.signUp();
cy.signUp("Chris", "Coding", "<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="2f4c475d465c6f4c404b464148014c4042">[email protected]</a>", "12345");
cy.signUp("Paul", "Coding", "<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="403021352c00232f24292e276e232f2d">[email protected]</a>", "12345");
cy.signUp("Adam", "Woodcock", "<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="ceafaaafa38eb9a1a1aaada1ada5e0ada1a3">[email protected]</a>", "12345");
cy.signUp("Kathleen", "Woodcock", "<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="4e252f3a26222b2b200e3921212a2d212d25602d2123">[email protected]</a>", "12345");
cy.signUp("George", "Hett", "<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="92f5f7fde0f5f7d2faf7e6e6bcf1fdff">[email protected]</a>", "12345");
cy.signUp("Rob", "Oman", "<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="4634292406292b27286825292b">[email protected]</a>", "12345");
});
it("Users can be searched by entering a name", () => {
cy.login();
cy.get("#searchBox").type("george");
cy.get("#searchButton").click();
cy.get(".user-container").first().should("contain", "George Hett");
});
it("Users can be searched by entering a last name", () => {
cy.login();
cy.get("#searchBox").type("woodcock");
cy.get("#searchButton").click();
cy.get(".user-container").should("have.length", 2);
cy.get(".user-container").should("contain", "Adam Woodcock");
cy.get(".user-container").should("contain", "Kathleen Woodcock");
});
it("A blank search returns all users", () => {
cy.login();
cy.get("#searchButton").click();
cy.get(".user-container").should("have.length", 7);
cy.get(".user-container").should("contain", "Adam Woodcock");
cy.get(".user-container").should("contain", "Kathleen Woodcock");
cy.get(".user-container").should("contain", "Chris Coding");
cy.get(".user-container").should("contain", "Paul Coding");
cy.get(".user-container").should("contain", "Rob Oman");
cy.get(".user-container").should("contain", "George Hett");
cy.get(".user-container").should("contain", "Barry Barry-Barroldsson");
});
it("Visiting the search page without going through the search bar returns all users", () => {
cy.login();
cy.visit("/search");
cy.get(".user-container").should("have.length", 7);
cy.get(".user-container").should("contain", "Adam Woodcock");
cy.get(".user-container").should("contain", "Kathleen Woodcock");
cy.get(".user-container").should("contain", "Chris Coding");
cy.get(".user-container").should("contain", "Paul Coding");
cy.get(".user-container").should("contain", "Rob Oman");
cy.get(".user-container").should("contain", "George Hett");
cy.get(".user-container").should("contain", "Barry Barry-Barroldsson");
});
it("The search should not be impacted by special characters", () => {
cy.login();
cy.get("#searchBox").type("Chris /.,[] Coding");
cy.get("#searchButton").click();
cy.get(".user-container").should("have.length", 2);
cy.get(".user-container").should("contain", "Chris Coding");
cy.get(".user-container").should("contain", "Paul Coding");
});
it("Each word entered should return relevant search results", () => {
cy.login();
cy.get("#searchBox").type("Chris Woodcock");
cy.get("#searchButton").click();
cy.get(".user-container").should("have.length", 3);
cy.get(".user-container").should("contain", "Adam Woodcock");
cy.get(".user-container").should("contain", "Kathleen Woodcock");
cy.get(".user-container").should("contain", "Chris Coding");
});
});
I would appreciate any recommendations on how to improve and fix the issues in this code