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

Refactored Nag Dialogs, Split UnableToAffordExpensesNagDialog into Two Dialogs, Added Unit Tests #4837

Merged
merged 32 commits into from
Sep 25, 2024
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
b0621ea
Updated Monthly Expenses Nag Dialog
IllianiCBT Sep 14, 2024
44d819a
Add functionality for "Unable to Afford Loan Payment" nag dialog
IllianiCBT Sep 14, 2024
aa73b09
Refactored handling of day end checks.
IllianiCBT Sep 14, 2024
53e757b
Add unit tests for DayEndingEvent and UnmaintainedUnitsNagDialog
IllianiCBT Sep 14, 2024
25aae29
Add missing licenses and enhance Javadoc
IllianiCBT Sep 14, 2024
622efc2
Add missing licenses and enhance Javadoc
IllianiCBT Sep 14, 2024
c1221e1
Merge remote-tracking branch 'origin/nag_collateral' into nag_collateral
IllianiCBT Sep 14, 2024
7f3167e
Finalized UnmaintainedUnitsNagDialogTest
IllianiCBT Sep 15, 2024
b65f263
Add unit tests for EndContractNagDialog and refactor code
IllianiCBT Sep 15, 2024
abfe3af
Add unit tests for InsufficientAstechsNagDialog
IllianiCBT Sep 15, 2024
1d4046b
Testing headless workaround
IllianiCBT Sep 15, 2024
cd7131e
Refactored InsufficientAstechsNagDialog logic
IllianiCBT Sep 15, 2024
c69506a
Refactor insufficient Astechs dialog unit test
IllianiCBT Sep 15, 2024
4daf94c
Refactored nag dialog classes and added unit tests
IllianiCBT Sep 15, 2024
f4f6369
Refactored comment format in nag dialog unit tests
IllianiCBT Sep 15, 2024
e4350e5
Refactor nag dialogs and add unit tests
IllianiCBT Sep 15, 2024
cc786c9
Refactor InvalidFactionNagDialog and add unit tests
IllianiCBT Sep 15, 2024
fe60a43
Remove redundant setup methods and improve NoCommanderNagDialog
IllianiCBT Sep 15, 2024
6834a7f
Refactored OutstandingScenariosNagDialog and added unit tests
IllianiCBT Sep 15, 2024
b7a6f0e
Refactor PregnantCombatantNagDialog and add tests
IllianiCBT Sep 16, 2024
a30cc87
Refactor PrisonersNagDialog and add unit tests
IllianiCBT Sep 16, 2024
91f9be7
Refactored ShortDeploymentNagDialog and added unit tests
IllianiCBT Sep 16, 2024
2f13fda
Enhance 'Unable to Afford Expenses' dialog
IllianiCBT Sep 16, 2024
eae3a3b
Refactor UnableToAffordJumpNagDialog and add unit tests
IllianiCBT Sep 16, 2024
e406c9e
Refactor and add tests for loan payment nag dialog
IllianiCBT Sep 16, 2024
42d3c6b
Add copyright headers to nag dialog test files
IllianiCBT Sep 16, 2024
0465ce6
Refactored and moved nagUnresolvedContacts method
IllianiCBT Sep 16, 2024
d0a6f76
Refactored and moved nagUnresolvedContacts method
IllianiCBT Sep 16, 2024
4c87eb5
Merge remote-tracking branch 'origin/nag_collateral' into nag_collateral
IllianiCBT Sep 16, 2024
3834df3
Improve code readability with Javadoc enhancements
IllianiCBT Sep 18, 2024
430cd4a
Merge branch 'MegaMek:master' into nag_collateral
IllianiCBT Sep 18, 2024
1ea5472
Corrected typo in PregnantCombatantNagDialog
IllianiCBT Sep 18, 2024
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
51 changes: 43 additions & 8 deletions MekHQ/src/mekhq/gui/dialog/nagDialogs/EndContractNagDialog.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2021 - 2024 The MegaMek Team. All Rights Reserved.
* Copyright (c) 2021-2024 The MegaMek Team. All Rights Reserved.
*
* This file is part of MekHQ.
*
Expand All @@ -21,24 +21,59 @@
import mekhq.MHQConstants;
import mekhq.MekHQ;
import mekhq.campaign.Campaign;
import mekhq.campaign.mission.Contract;
import mekhq.gui.baseComponents.AbstractMHQNagDialog;

import javax.swing.*;
import java.time.temporal.ChronoUnit;
import java.time.LocalDate;

/**
* This class represents a nag dialog displayed on the day a contract ends
* It extends the AbstractMHQNagDialog class.
*/
public class EndContractNagDialog extends AbstractMHQNagDialog {
private static boolean isContractEnded (Campaign campaign) {
// we can use 'is date y after x', as once the end date has been passed,
static String DIALOG_NAME = "EndContractNagDialog";
static String DIALOG_TITLE = "EndContractNagDialog.title";
static String DIALOG_BODY = "EndContractNagDialog.text";

/**
* Checks if a contract within a campaign has ended on the current date.
*
* @param campaign the campaign containing the contracts to be checked
* @return {@code true} if a contract within the campaign has ended on the current date,
* {@code false} otherwise
*/
static boolean isContractEnded(Campaign campaign) {
LocalDate today = campaign.getLocalDate();

// we can't use 'is date y after x', as once the end date has been passed,
// the contract is removed from the list of active contracts
return campaign.getActiveContracts().stream()
.anyMatch(contract -> ChronoUnit.DAYS.between(campaign.getLocalDate(), contract.getEndingDate()) == 0);

// there is no reason to use a stream here, as there won't be enough iterations to warrant it
for (Contract contract : campaign.getActiveContracts()) {
if (contract.getEndingDate().equals(today)) {
return true;
}
}

return false;
}

/**
* Creates a new instance of the EndContractNagDialog class.
*
* @param frame the parent JFrame for the dialog
* @param campaign the Campaign associated with the dialog
*/
public EndContractNagDialog(final JFrame frame, final Campaign campaign) {
super(frame, "EndContractNagDialog", "EndContractNagDialog.title",
"EndContractNagDialog.text", campaign, MHQConstants.NAG_CONTRACT_ENDED);
super(frame, DIALOG_NAME, DIALOG_TITLE, DIALOG_BODY, campaign, MHQConstants.NAG_CONTRACT_ENDED);
}

/**
* Checks if there is a nag message to display.
*
* @return {@code true} if there is a nag message to display, {@code false} otherwise
*/
@Override
protected boolean checkNag() {
return !MekHQ.getMHQOptions().getNagDialogIgnore(getKey())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,10 +50,10 @@ static boolean checkHanger(Campaign campaign) {
}

/**
* Constructs a new UnmaintainedUnitsNagDialog.
* Creates a new instance of the UnmaintainedUnitsNagDialog class.
*
* @param frame the parent JFrame for the dialog
* @param campaign the Campaign object associated with the dialog
* @param frame the parent JFrame for the dialog
* @param campaign the Campaign associated with the dialog
IllianiCBT marked this conversation as resolved.
Show resolved Hide resolved
*/
//region Constructors
public UnmaintainedUnitsNagDialog(final JFrame frame, final Campaign campaign) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
package mekhq.gui.dialog.nagDialogs;
IllianiCBT marked this conversation as resolved.
Show resolved Hide resolved

import megamek.logging.MMLogger;
import mekhq.campaign.Campaign;
import mekhq.campaign.mission.Contract;
import mekhq.campaign.universe.Systems;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;

import java.time.LocalDate;
import java.util.ArrayList;
import java.util.List;

import static mekhq.gui.dialog.nagDialogs.EndContractNagDialog.isContractEnded;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

/**
* This class is a test class for the EndContractNagDialog class.
* It contains test methods for various scenarios related to contract expiration.
*/
public class EndContractNagDialogTest {
// Mock objects for the tests
private Campaign campaign;
private LocalDate today;
private Contract contract1, contract2;

/**
* Sets up the necessary dependencies and configurations before running the test methods.
* Runs once before all tests
*/
@BeforeAll
static void setup() {
try {
Systems.setInstance(Systems.loadDefault());
} catch (Exception exception) {
MMLogger.create(EndContractNagDialogTest.class).error("", exception);
}
}

/**
* Test setup for each test, runs before each test.
* Initializes the mock objects and sets up the necessary mock behaviors.
*/
@BeforeEach
void init() {
// Initialize the mock objects
campaign = mock(Campaign.class);
today = LocalDate.now();
contract1 = mock(Contract.class);
contract2 = mock(Contract.class);

// When the Campaign mock calls 'getLocalDate()' return today's date
when(campaign.getLocalDate()).thenReturn(today);
}

// In the following tests,
// Different combinations of contract end date states to set up desired behaviors in mock objects
// Then the isContractEnded() method of EndContractNagDialog class is called,
// and its response is checked against expected behavior

@Test
void noActiveContracts() {
when(campaign.getActiveContracts()).thenReturn(new ArrayList<>());
assertFalse(isContractEnded(campaign));
}

@Test
void oneActiveContractEndsTomorrow() {
when(campaign.getActiveContracts()).thenReturn(List.of(contract1));
when(contract1.getEndingDate()).thenReturn(today.plusDays(1));
assertFalse(isContractEnded(campaign));
}

@Test
void oneActiveContractEndsToday() {
when(campaign.getActiveContracts()).thenReturn(List.of(contract1));
when(contract1.getEndingDate()).thenReturn(today);
assertTrue(isContractEnded(campaign));
}

@Test
void twoActiveContractsOneEndsTomorrowOneEndsToday() {
when(campaign.getActiveContracts()).thenReturn(List.of(contract1, contract2));
when(contract1.getEndingDate()).thenReturn(today.plusDays(1));
when(contract2.getEndingDate()).thenReturn(today);
assertTrue(isContractEnded(campaign));
}

@Test
void twoActiveContractsBothEndToday() {
when(campaign.getActiveContracts()).thenReturn(List.of(contract1, contract2));
when(contract1.getEndingDate()).thenReturn(today);
assertTrue(isContractEnded(campaign));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
package mekhq.gui.dialog.nagDialogs;

import megamek.logging.MMLogger;
import mekhq.campaign.Campaign;
import mekhq.campaign.universe.Systems;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;

import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

class InsufficientAstechsNagDialogTest {
// Mock objects for the tests
private Campaign campaign;
private InsufficientAstechsNagDialog dialog;

/**
* Sets up the necessary dependencies and configurations before running the test methods.
* Runs once before all tests
*/
@BeforeAll
static void setup() {
try {
Systems.setInstance(Systems.loadDefault());
} catch (Exception exception) {
MMLogger.create(InsufficientAstechsNagDialogTest.class).error("", exception);
}
}

/**
* Test setup for each test, runs before each test.
* Initializes the mock objects and sets up the necessary mock behaviors.
*/
@BeforeEach
void init() {
campaign = mock(Campaign.class);
dialog = new InsufficientAstechsNagDialog(null, campaign);
}

// In the following tests,
// Different combinations of unit states to set up desired behaviors in mock objects
// Then the checkNag() method of InsufficientAstechsNagDialog class is called,
// and its response is checked against expected behavior

@Test
void noAstechsNeeded() {
when(campaign.getAstechNeed()).thenReturn(0);
assertFalse(dialog.checkNag());
}

@Test
void oneAstechNeeded() {
when(campaign.getAstechNeed()).thenReturn(1);
assertTrue(dialog.checkNag());
}

@Test
void negativeAstechsNeeded() {
when(campaign.getAstechNeed()).thenReturn(-1);
assertFalse(dialog.checkNag());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,9 @@
*/
class UnmaintainedUnitsNagDialogTest {
// Mock objects for the tests
Campaign campaign;
Hangar hangar;
Unit mockUnit1, mockUnit2;
private Campaign campaign;
private Hangar hangar;
private Unit mockUnit1, mockUnit2;

/**
* Sets up the necessary dependencies and configurations before running the test methods.
Expand Down Expand Up @@ -129,14 +129,14 @@ void unmaintainedUnitExistsButSalvageMixed() {
}

@Test
void noUoUnmaintainedUnitExistsUnit1() {
void noUnmaintainedUnitExistsNoSalvage() {
initializeUnits(false, false, false, false);
assertFalse(checkHanger(campaign));
}

@Test
void noUnmaintainedUnitExistsUnit2() {
initializeUnits(false, false, false, false);
void noUnmaintainedUnitExistsAllSalvage() {
initializeUnits(false, true, false, true);
assertFalse(checkHanger(campaign));
}

Expand Down
Loading