Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
102 changes: 102 additions & 0 deletions src/test/java/com/taskflow/model/TaskModelTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
package com.taskflow.model;

import org.junit.jupiter.api.Test;

import static org.junit.jupiter.api.Assertions.*;

/**
* Unit tests for the {@link Task} model.
*
* <p>Bug pins for {@link Task#toString()}:
* <ul>
* <li>If {@code assignee_id} is null, {@code assignee_id.toString()} throws NPE.</li>
* <li>If {@code due_date} is null, {@code due_date.trim()} throws NPE.</li>
* </ul>
*/
class TaskModelTest {

// --- constructor tests ---

@Test
void shortConstructor_setsFieldsCorrectly() {
Task task = new Task("Fix login", 3, "bug", "Login fails on empty password", 42L);
assertEquals("Fix login", task.getTitle());
assertEquals(3, task.getPriority());
assertEquals("bug", task.type);
assertEquals("Fix login", task.getTitle());
assertEquals(42L, task.assignee_id);
assertEquals(0, task.getStatus()); // default status is 0 (todo)
assertNotNull(task.createdDate);
}

@Test
void defaultConstructor_allFieldsDefaultToNull() {
Task task = new Task();
assertNull(task.getId());
assertNull(task.getTitle());
assertEquals(0, task.getStatus());
assertEquals(0, task.getPriority());
}

// --- toString() NPE bug-pin tests ---

/**
* Bug pin: Task.toString() calls assignee_id.toString() without null check.
* Constructing a Task via no-arg constructor leaves assignee_id=null β†’ NPE.
*/
@Test
void toString_nullAssigneeId_throwsNPE() {
Task task = new Task();
task.setTitle("Test task");
task.due_date = "2026-01-01";
// BUG: assignee_id.toString() throws NullPointerException
assertThrows(NullPointerException.class, task::toString);
}

/**
* Bug pin: Task.toString() calls due_date.trim() without null check.
*/
@Test
void toString_nullDueDate_throwsNPE() {
Task task = new Task();
task.setTitle("Test task");
task.assignee_id = 1L;
// due_date is null β†’ BUG: due_date.trim() throws NullPointerException
assertThrows(NullPointerException.class, task::toString);
}

/**
* Bug pin: Task constructed via no-arg constructor has null assignee_id and due_date;
* calling toString() throws NPE even for a task that is otherwise valid.
*/
@Test
void toString_defaultConstructorFields_throwsNPE() {
Task task = new Task();
task.setTitle("Minimal task");
assertThrows(NullPointerException.class, task::toString);
}

/**
* Positive case: toString() succeeds when both assignee_id and due_date are set.
*/
@Test
void toString_allRequiredFieldsSet_noException() {
Task task = new Task();
task.setTitle("Deploy");
task.setStatus(1);
task.assignee_id = 7L;
task.due_date = "2026-12-31";
String result = assertDoesNotThrow(task::toString);
assertTrue(result.contains("Deploy"));
assertTrue(result.contains("7"));
}

// --- attachmentUrls initial state ---

@Test
void attachmentUrls_initializedAsEmptyList() {
Task task = new Task();
assertNotNull(task.attachmentUrls);
assertTrue(task.attachmentUrls.isEmpty());
}
}
121 changes: 121 additions & 0 deletions src/test/java/com/taskflow/model/UserModelTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
package com.taskflow.model;

import org.junit.jupiter.api.Test;

import static org.junit.jupiter.api.Assertions.*;

/**
* Unit tests for {@link User#getDisplayName()}.
*
* <p>getDisplayName() has three branches:
* <ol>
* <li>Both firstName AND lastName non-null β†’ "firstName lastName"</li>
* <li>Either first/last is null, but full_name non-null β†’ full_name</li>
* <li>full_name also null β†’ username</li>
* </ol>
*
* <p>Bug documented: if firstName is set but lastName is null (or vice versa),
* the set name is silently ignored and the method falls through to full_name/username.
*/
class UserModelTest {

// --- happy path ---

@Test
void getDisplayName_bothFirstAndLastName_returnsCombined() {
User user = new User("jsmith", "j@example.com", "pass");
user.setFirstName("John");
user.setLastName("Smith");
assertEquals("John Smith", user.getDisplayName());
}

@Test
void getDisplayName_noFirstOrLastName_usesFullName() {
User user = new User("jsmith", "j@example.com", "pass");
user.setFull_name("John Smith");
assertEquals("John Smith", user.getDisplayName());
}

@Test
void getDisplayName_noNamesAtAll_usesUsername() {
User user = new User("jsmith", "j@example.com", "pass");
assertEquals("jsmith", user.getDisplayName());
}

// --- bug-pin tests: partial name silently ignored ---

/**
* Bug pin: firstName set but lastName is null.
* The caller might expect "John" but the method skips to full_name/username.
* Current (buggy) behaviour: falls through to full_name if set, else username.
*/
@Test
void getDisplayName_firstNameSetButLastNameNull_fallsBackToFullName() {
User user = new User("jsmith", "j@example.com", "pass");
user.setFirstName("John");
// lastName is null; full_name is set
user.setFull_name("John Smith (full)");
// BUG: firstName is ignored; full_name is returned instead
assertEquals("John Smith (full)", user.getDisplayName());
}

@Test
void getDisplayName_firstNameSetLastNameNullNoFullName_fallsBackToUsername() {
User user = new User("jsmith", "j@example.com", "pass");
user.setFirstName("John");
// lastName is null; full_name is also null
// BUG: the caller-supplied firstName is silently discarded
assertEquals("jsmith", user.getDisplayName());
}

@Test
void getDisplayName_lastNameSetButFirstNameNull_fallsBackToUsername() {
User user = new User("jsmith", "j@example.com", "pass");
user.setLastName("Smith");
// firstName is null; full_name is also null
// BUG: the caller-supplied lastName is silently discarded
assertEquals("jsmith", user.getDisplayName());
}

// --- precedence ---

/**
* firstName+lastName wins over full_name when both are set.
*/
@Test
void getDisplayName_firstAndLastNamePrecedeFullName() {
User user = new User("jsmith", "j@example.com", "pass");
user.setFirstName("John");
user.setLastName("Smith");
user.setFull_name("J. Smith (legacy)");
assertEquals("John Smith", user.getDisplayName());
}

/**
* full_name wins over username when first/last are missing.
*/
@Test
void getDisplayName_fullNamePrecedesUsername() {
User user = new User("jsmith", "j@example.com", "pass");
user.setFull_name("John Smith");
assertEquals("John Smith", user.getDisplayName());
}

// --- edge cases ---

@Test
void getDisplayName_emptyFirstAndLastName_returnsSpaceSeparated() {
// Both are non-null (empty strings) β†’ concatenated as " "
User user = new User("jsmith", "j@example.com", "pass");
user.setFirstName("");
user.setLastName("");
assertEquals(" ", user.getDisplayName());
}

@Test
void getDisplayName_defaultConstructor_noNPE() {
User user = new User();
// All name fields are null; username is null too β†’ returns null (no NPE)
assertNull(user.getDisplayName());
}
}