Skip to content

Commit

Permalink
Merge pull request #63 from ahmadsyuaib/branch-find-phone-number
Browse files Browse the repository at this point in the history
Add findPhone command
  • Loading branch information
jereeemyyyy authored Oct 15, 2024
2 parents 97107b3 + 9755f4b commit 9831156
Show file tree
Hide file tree
Showing 8 changed files with 367 additions and 0 deletions.
58 changes: 58 additions & 0 deletions src/main/java/seedu/address/logic/commands/FindPhoneCommand.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
package seedu.address.logic.commands;

import static java.util.Objects.requireNonNull;

import seedu.address.commons.util.ToStringBuilder;
import seedu.address.logic.Messages;
import seedu.address.model.Model;
import seedu.address.model.person.PhoneBeginsWithKeywordPredicate;

/**
* Finds and lists all persons in address book whose phone number begins with the argument keywords.
* Keyword matching has to be all numbers.
*/
public class FindPhoneCommand extends Command {

public static final String COMMAND_WORD = "fp";

public static final String MESSAGE_USAGE = COMMAND_WORD + ": Finds all persons whose phone number begins with "
+ "the specified keywords (integers only with no spacing) and displays them as a list with index numbers.\n"
+ "Parameters: integers \n"
+ "Example: " + COMMAND_WORD + " 91234567";

private final PhoneBeginsWithKeywordPredicate predicate;

public FindPhoneCommand(PhoneBeginsWithKeywordPredicate predicate) {
this.predicate = predicate;
}

@Override
public CommandResult execute(Model model) {
requireNonNull(model);
model.updateFilteredPersonList(predicate);
return new CommandResult(
String.format(Messages.MESSAGE_PERSONS_LISTED_OVERVIEW, model.getFilteredPersonList().size()));
}

@Override
public boolean equals(Object other) {
if (other == this) {
return true;
}

// instanceof handles nulls
if (!(other instanceof FindPhoneCommand)) {
return false;
}

FindPhoneCommand otherFindCommand = (FindPhoneCommand) other;
return predicate.equals(otherFindCommand.predicate);
}

@Override
public String toString() {
return new ToStringBuilder(this)
.add("predicate", predicate)
.toString();
}
}
4 changes: 4 additions & 0 deletions src/main/java/seedu/address/logic/parser/ClientHubParser.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
import seedu.address.logic.commands.EditCommand;
import seedu.address.logic.commands.ExitCommand;
import seedu.address.logic.commands.FindCommand;
import seedu.address.logic.commands.FindPhoneCommand;
import seedu.address.logic.commands.HelpCommand;
import seedu.address.logic.commands.ListCommand;
import seedu.address.logic.parser.exceptions.ParseException;
Expand Down Expand Up @@ -77,6 +78,9 @@ public Command parseCommand(String userInput) throws ParseException {
case HelpCommand.COMMAND_WORD:
return new HelpCommand();

case FindPhoneCommand.COMMAND_WORD:
return new FindPhoneCommandParser().parse(arguments);

default:
logger.finer("This user input caused a ParseException: " + userInput);
throw new ParseException(MESSAGE_UNKNOWN_COMMAND);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package seedu.address.logic.parser;

import static seedu.address.logic.Messages.MESSAGE_INVALID_COMMAND_FORMAT;

import seedu.address.logic.commands.FindPhoneCommand;
import seedu.address.logic.parser.exceptions.ParseException;
import seedu.address.model.person.PhoneBeginsWithKeywordPredicate;

/**
* Parses input arguments and creates a new FindPhoneCommand object
*/
public class FindPhoneCommandParser implements Parser<FindPhoneCommand> {

/**
* Parses the given {@code String} of arguments in the context of the FindCommand
* and returns a FindPhoneNumberCommand object for execution.
* @throws ParseException if the user input does not conform the expected format
*/
public FindPhoneCommand parse(String args) throws ParseException {
String trimmedArgs = args.trim();

if (trimmedArgs.isEmpty() || !trimmedArgs.matches("\\d+")) {
throw new ParseException(
String.format(MESSAGE_INVALID_COMMAND_FORMAT, FindPhoneCommand.MESSAGE_USAGE));
}

String[] phoneNumber = trimmedArgs.split("\\s+");

if (phoneNumber.length != 1) {
throw new ParseException(
String.format(MESSAGE_INVALID_COMMAND_FORMAT, FindPhoneCommand.MESSAGE_USAGE));
}

return new FindPhoneCommand(new PhoneBeginsWithKeywordPredicate(phoneNumber[0]));
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package seedu.address.model.person;

import java.util.function.Predicate;

import seedu.address.commons.util.ToStringBuilder;

/**
* Tests that a {@code Person}'s {@code Phone} matches any of the keywords given.
*/
public class PhoneBeginsWithKeywordPredicate implements Predicate<Person> {
private final String keyword;

public PhoneBeginsWithKeywordPredicate(String keyword) {
this.keyword = keyword;
}

@Override
public boolean test(Person person) {
if (keyword.isEmpty()) {
return false;
}
return person.getPhone().value.startsWith(keyword);
}

@Override
public boolean equals(Object other) {
if (other == this) {
return true;
}

// instanceof handles nulls
if (!(other instanceof PhoneBeginsWithKeywordPredicate)) {
return false;
}

PhoneBeginsWithKeywordPredicate otherPhoneBeginsWithKeywordPredicate = (PhoneBeginsWithKeywordPredicate) other;
return keyword.equals(otherPhoneBeginsWithKeywordPredicate.keyword);
}

@Override
public String toString() {
return new ToStringBuilder(this).add("keyword", keyword).toString();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
package seedu.address.logic.commands;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static seedu.address.logic.Messages.MESSAGE_PERSONS_LISTED_OVERVIEW;
import static seedu.address.logic.commands.CommandTestUtil.assertCommandSuccess;
import static seedu.address.testutil.TypicalPersons.ELLE;
import static seedu.address.testutil.TypicalPersons.FIONA;
import static seedu.address.testutil.TypicalPersons.GEORGE;
import static seedu.address.testutil.TypicalPersons.getTypicalClientHub;

import java.util.Arrays;
import java.util.Collections;

import org.junit.jupiter.api.Test;

import seedu.address.model.Model;
import seedu.address.model.ModelManager;
import seedu.address.model.UserPrefs;
import seedu.address.model.person.PhoneBeginsWithKeywordPredicate;

/**
* Contains integration tests (interaction with the Model) for {@code FindCommand}.
*/
public class FindPhoneCommandTest {
private Model model = new ModelManager(getTypicalClientHub(), new UserPrefs());
private Model expectedModel = new ModelManager(getTypicalClientHub(), new UserPrefs());

@Test
public void equals() {
PhoneBeginsWithKeywordPredicate firstPredicate =
new PhoneBeginsWithKeywordPredicate("9876");
PhoneBeginsWithKeywordPredicate secondPredicate =
new PhoneBeginsWithKeywordPredicate("9678");

FindPhoneCommand findPhoneFirstCommand = new FindPhoneCommand(firstPredicate);
FindPhoneCommand findPhoneSecondCommand = new FindPhoneCommand(secondPredicate);

// same object -> returns true
assertTrue(findPhoneFirstCommand.equals(findPhoneFirstCommand));

// same values -> returns true
FindPhoneCommand findPhoneFirstCommandCopy = new FindPhoneCommand(firstPredicate);
assertTrue(findPhoneFirstCommand.equals(findPhoneFirstCommandCopy));

// different types -> returns false
assertFalse(findPhoneFirstCommand.equals(1));

// null -> returns false
assertFalse(findPhoneFirstCommand.equals(null));

// different person -> returns false
assertFalse(findPhoneFirstCommand.equals(findPhoneSecondCommand));
}

@Test
public void execute_zeroKeywords_noPhoneFound() {
String expectedMessage = String.format(MESSAGE_PERSONS_LISTED_OVERVIEW, 0);
PhoneBeginsWithKeywordPredicate predicate = preparePredicate(" ");
FindPhoneCommand command = new FindPhoneCommand(predicate);
expectedModel.updateFilteredPersonList(predicate);
assertCommandSuccess(command, model, expectedMessage, expectedModel);
assertEquals(Collections.emptyList(), model.getFilteredPersonList());
}

@Test
public void execute_singleKeyword_multiplePersonsFound() {
String expectedMessage = String.format(MESSAGE_PERSONS_LISTED_OVERVIEW, 3);
PhoneBeginsWithKeywordPredicate predicate = preparePredicate("948");
FindPhoneCommand command = new FindPhoneCommand(predicate);
expectedModel.updateFilteredPersonList(predicate);
assertCommandSuccess(command, model, expectedMessage, expectedModel);
assertEquals(Arrays.asList(ELLE, FIONA, GEORGE), model.getFilteredPersonList());
}

@Test
public void toStringMethod() {
PhoneBeginsWithKeywordPredicate predicate = new PhoneBeginsWithKeywordPredicate("keyword");
FindPhoneCommand findPhoneCommand = new FindPhoneCommand(predicate);
String expected = FindPhoneCommand.class.getCanonicalName() + "{predicate=" + predicate + "}";
assertEquals(expected, findPhoneCommand.toString());
}

/**
* Parses {@code userInput} into a {@code NameContainsKeywordsPredicate}.
*/
private PhoneBeginsWithKeywordPredicate preparePredicate(String userInput) {
return new PhoneBeginsWithKeywordPredicate(userInput);
}
}
10 changes: 10 additions & 0 deletions src/test/java/seedu/address/logic/parser/ClientHubParserTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,13 @@
import seedu.address.logic.commands.EditCommand.EditPersonDescriptor;
import seedu.address.logic.commands.ExitCommand;
import seedu.address.logic.commands.FindCommand;
import seedu.address.logic.commands.FindPhoneCommand;
import seedu.address.logic.commands.HelpCommand;
import seedu.address.logic.commands.ListCommand;
import seedu.address.logic.parser.exceptions.ParseException;
import seedu.address.model.person.NameContainsKeywordsPredicate;
import seedu.address.model.person.Person;
import seedu.address.model.person.PhoneBeginsWithKeywordPredicate;
import seedu.address.testutil.EditPersonDescriptorBuilder;
import seedu.address.testutil.PersonBuilder;
import seedu.address.testutil.PersonUtil;
Expand Down Expand Up @@ -88,6 +90,14 @@ public void parseCommand_list() throws Exception {
assertTrue(parser.parseCommand(ListCommand.COMMAND_WORD + " 3") instanceof ListCommand);
}

@Test
public void parseCommand_findPhone() throws Exception {
String keyword = "9876";
FindPhoneCommand command = (FindPhoneCommand) parser.parseCommand(
FindPhoneCommand.COMMAND_WORD + " " + keyword);
assertEquals(new FindPhoneCommand(new PhoneBeginsWithKeywordPredicate(keyword)), command);
}

@Test
public void parseCommand_unrecognisedInput_throwsParseException() {
assertThrows(ParseException.class, String.format(MESSAGE_INVALID_COMMAND_FORMAT, HelpCommand.MESSAGE_USAGE), ()
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package seedu.address.logic.parser;

import static seedu.address.logic.Messages.MESSAGE_INVALID_COMMAND_FORMAT;
import static seedu.address.logic.parser.CommandParserTestUtil.assertParseFailure;
import static seedu.address.logic.parser.CommandParserTestUtil.assertParseSuccess;

import org.junit.jupiter.api.Test;

import seedu.address.logic.commands.FindPhoneCommand;
import seedu.address.model.person.PhoneBeginsWithKeywordPredicate;

public class FindPhoneCommandParserTest {

private FindPhoneCommandParser parser = new FindPhoneCommandParser();

@Test
public void parse_emptyArg_throwsParseException() {
assertParseFailure(parser, " ",
String.format(MESSAGE_INVALID_COMMAND_FORMAT, FindPhoneCommand.MESSAGE_USAGE));
}

@Test
public void parse_validArgs_returnsFindCommand() {
// no leading and trailing whitespaces
FindPhoneCommand expectedFindCommand =
new FindPhoneCommand(new PhoneBeginsWithKeywordPredicate("9876"));
assertParseSuccess(parser, "9876", expectedFindCommand);
}

@Test
public void parse_invalidArgs_throwsParseException() {
// multiple inputs
assertParseFailure(parser, "9876 9678",
String.format(MESSAGE_INVALID_COMMAND_FORMAT, FindPhoneCommand.MESSAGE_USAGE));


// not number
assertParseFailure(parser, "string",
String.format(MESSAGE_INVALID_COMMAND_FORMAT, FindPhoneCommand.MESSAGE_USAGE));


// non-number in betweennumber
assertParseFailure(parser, "987n9678",
String.format(MESSAGE_INVALID_COMMAND_FORMAT, FindPhoneCommand.MESSAGE_USAGE));
}

}
Loading

0 comments on commit 9831156

Please sign in to comment.