Skip to main content

Test Mapping: Fee Lifecycle Management

This document describes how to implement the automation for FeeLifecycle.feature.

Target Component

  • Controller: WepNG_MVC.Controllers.FeeController
  • Methods: Create, Edit, Delete
  • Service: EITWEP.Business.FeeService.Validate(...) (Internal logic)

Dependencies to Mock

The FeeController is legacy and tightly coupled. For Phase A (Integration), we will interact with the real WEPV2DataContext using a Test Transaction.

  • DbContext: Real WEPV2DataContext (Scoped in Transaction).
  • UserContext: Mocked via Controller.ControllerContext.
  • ApplicationContext: Mock MasterCultures in WepApplicationContext (Singleton).

Step Definitions (Pseudo-Code)

Given the System has the following Master Cultures...

[Given(@"the System has the following Master Cultures initialized:")]
public void GivenMasterCultures(Table table) {
// 1. Mock Singleton (Dangerous in parallel tests)
var ctxMock = Mock.Get(WepApplicationContext.getInstance());
var cultures = table.CreateSet<WepCulture>();
ctxMock.Setup(c => c.MasterCultures).Returns(cultures.ToDictionary(c => c.Id, c => c.Title));
}

Given a Fee exists with...

[Given(@"a Fee exists with the following properties:")]
public void GivenAFeeExists(Table table) {
// 1. Arrange: Parse table to Fee entity
var fee = table.CreateInstance<Fee>();

// 2. Act: Insert directly into DB to simulate "Existing State"
using (var db = new WEPV2DataContext()) {
db.Fees.InsertOnSubmit(fee);
db.SubmitChanges();
}

// 3. Cleanup: Register ID for teardown
_cleanupList.Add(fee.ID);
}

When I attempt to create a new Fee with...

[When(@"I attempt to create a new Fee with:")]
public void WhenIAttemptToCreate(Table table) {
// 1. Arrange: Prepare Controller
var controller = new FeeController();
var model = table.CreateInstance<FeeViewModel>(); // Mapper needed

// 2. Act: Call the Action
// Note: We might need to simulate ModelState validation manually if not running full HTTP stack
_actionResult = controller.Create(model);
}

Then the creation should be rejected

[Then(@"the creation should be rejected")]
public void ThenRejected() {
// 1. Assert: Check Action Result type
_actionResult.Should().BeOfType<ViewResult>(); // Returns to View on error

// 2. Assert: Check ModelState
var viewResult = _actionResult as ViewResult;
viewResult.ViewData.ModelState.IsValid.Should().BeFalse();
}

### `And the error "..." should be displayed for "..."`
```csharp
[Then(@"the error ""(.*)"" should be displayed for ""(.*)""")]
public void ThenKeyedError(string msg, string key) {
var viewResult = _actionResult as ViewResult;
viewResult.ViewData.ModelState[key].Errors.Should().Contain(e => e.ErrorMessage == msg);
}

And the Fee should be linked to Accommodation Type...

[Then(@"the Fee should be linked to Accommodation Type ""(.*)""")]
public void ThenLinkedToAcc(string accTitle) {
// 1. Fetch created fee
var fee = _db.Fees.First(f => f.FEECode == "FEE_ACC");

// 2. Assert: Check Relation
// Logic from Controller: db.RelAccomodationTypeFeeNGs.Add(relAccFee);
fee.RelAccomodationTypeFeeNGs.Should().Contain(r => r.AccomodationTypeNG.Title == accTitle);
}

When I attempt to update the Fee...

[When(@"I attempt to update the Fee ""(.*)"" with:")]
public void WhenUpdate(string code, Table table) {
var fee = _db.Fees.FirstOrDefault(f => f.FEECode == code);
// Bind table to fee object
// Call controller.Edit(fee);
}

When I delete the Fee...

[When(@"I delete the Fee ""(.*)""")]
public void WhenDelete(string code) {
var fee = _db.Fees.First(f => f.FEECode == code);
// Call controller.Delete(fee.FEEID);
}

When I clone the Fee...

[When(@"I clone the Fee ""(.*)""")]
public void WhenClone(string code) {
var fee = _db.Fees.First(f => f.FEECode == code);
// Call controller.Duplicate(fee.FEEID);
}

When I generate combinations for...

[When(@"I generate combinations for ""(.*)"" with:")]
public void WhenGenerate(string code, Table table) {
// Requires mocking FeeFactory or Controller.FeeCombinaisonSave
// This is a complex Side-Effect!
}

## Questions / Risks
1. **Auth**: does `FeeController` require `[Authorize]`? *Yes*. We might need to mock the User Principal in the test setup.
2. **Database**: Validation might depend on Triggers? *No, looks like C# logic*.