Skip to content
Merged
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
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ public class CustomWebApplicationFactory : WebApplicationFactory<CrowdedBackend.
{
protected override void ConfigureWebHost(IWebHostBuilder builder)
{

builder.UseEnvironment("Testing");
builder.ConfigureServices(services =>
{
Expand All @@ -27,7 +28,7 @@ protected override void ConfigureWebHost(IWebHostBuilder builder)
services.AddScoped<CircleUtils>();

// Unique DB name per test class
var dbName = $"TestDb_{GetType().Name}";
var dbName = $"TestDb_{GetType().Name}_{Guid.NewGuid()}";

services.AddDbContext<MyDbContext>(options =>
options.UseInMemoryDatabase(dbName));
Expand All @@ -38,6 +39,26 @@ protected override void ConfigureWebHost(IWebHostBuilder builder)
var db = scope.ServiceProvider.GetRequiredService<MyDbContext>();
db.Database.EnsureDeleted(); // Clean slate
db.Database.EnsureCreated();


// Seed the database
db.Venue.Add(new Venue { VenueID = 4, VenueName = "Test Venue" });
db.Venue.Add(new Venue { VenueID = 99, VenueName = "Venue to Delete" });
db.Venue.Add(new Venue { VenueID = 98, VenueName = "Second Venue to Delete" });

db.RaspData.Add(new RaspData { Id = 998, MacAddress = "79:1C:89:6B:EC:C7", RaspId = 1, Rssi = -90, UnixTimestamp = 1746033900000 });
db.RaspData.Add(new RaspData { Id = 999, MacAddress = "79:1C:89:6B:EC:C7", RaspId = 1, Rssi = -90, UnixTimestamp = 1746033900000 });

db.DetectedDevice.Add(new DetectedDevice { DetectedDeviceId = 999, DeviceX = 50, DeviceY = 70, Timestamp = 1746535200000, VenueID = 4 });
db.DetectedDevice.Add(new DetectedDevice { DetectedDeviceId = 998, DeviceX = 60, DeviceY = 90, Timestamp = 1746535200000, VenueID = 4 });
db.DetectedDevice.Add(new DetectedDevice { DetectedDeviceId = 997, DeviceX = 80, DeviceY = 40, Timestamp = 1746535200000, VenueID = 4 });

// Adding Raspberry Pi devices to the database
db.RaspberryPi.Add(new RaspberryPi { VenueID = 10, RaspX = 50, RaspY = 60 });
db.RaspberryPi.Add(new RaspberryPi { VenueID = 10, RaspX = 90, RaspY = 100 });
db.RaspberryPi.Add(new RaspberryPi { VenueID = 10, RaspX = 50, RaspY = 30 });

db.SaveChanges();
});
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ public class DetectedDevicesIntegrationTests : IClassFixture<CustomWebApplicatio
private readonly HttpClient _client;
private readonly CustomWebApplicationFactory _factory;
private readonly ITestOutputHelper _TestOutput;
private long timestamp = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();



public DetectedDevicesIntegrationTests(CustomWebApplicationFactory factory, ITestOutputHelper TestOutput)
Expand All @@ -24,68 +24,57 @@ public DetectedDevicesIntegrationTests(CustomWebApplicationFactory factory, ITes
_client = _factory.CreateClient();
}


/// <summary>
/// testing GetLatestValidHeatmap endpoint
/// </summary>
/// <remark>
/// Expected to pass by checking the response code
/// Also if the responseContent is not null because we expect a bitstring
/// </remark>
[Fact]
public async Task GetHeatmapAtSpecificTime_returnBitstring()
public async Task GetLatestValidHeatmap_returnBitstring()
{
// Arrange: Create a Venue object to send to the API
var venue = new Venue { VenueName = "TestVenue" };

// Act: Send the POST request to the /api/Venue endpoint
await _client.PostAsJsonAsync("/api/Venue", venue);


// Arrange
timestamp -= (timestamp % 30000); // same TimeInterval used in controller
var detectedDevice = new DetectedDevice
{
DeviceX = 50,
DeviceY = 100,
Timestamp = timestamp,
VenueID = venue.VenueID,
};

await _client.PostAsJsonAsync("/api/DetectedDevices", detectedDevice);

var result = await _client.GetAsync($"/api/DetectedDevices/getHeatmapAtSpecificTime/{timestamp}");
var result = await _client.GetAsync($"api/DetectedDevices/getLatestValidHeatmap");
var responseContent = await result.Content.ReadAsStringAsync();
result.EnsureSuccessStatusCode();

// Assert
Assert.False(string.IsNullOrWhiteSpace(responseContent));
_TestOutput.WriteLine(responseContent);
}

/// <summary>
/// Testing uploadmultiple endpoint by using dummy data from a file
/// </summary>
/// <remark>
/// Expected to pass by checking the response code
/// Also if the statuscode matches the expected
/// </remark>
[Fact]
public async Task HandleRaspPostRequest_test()
{
// Arrange

var filePath = Path.Combine(Directory.GetCurrentDirectory(), "Data", "raspOutputData.json");

var raspOutputData = JsonSerializer.Deserialize<RaspOutputData>(
File.ReadAllText(filePath),
new JsonSerializerOptions { PropertyNameCaseInsensitive = true });

var response = await _client.PostAsJsonAsync("/api/detectedDevices/uploadMultiple", raspOutputData);
response.EnsureSuccessStatusCode();
_TestOutput.WriteLine($"response : {response}");


// Assert
Assert.Equal(HttpStatusCode.Created, response.StatusCode);
}

/// <summary>
/// testing get detectedDevice
/// </summary>
/// <remark>
/// Expected to pass by checking the response code
/// Also if the list of DetectedDevices are not null nor empty
/// </remark>
[Fact]
public async Task CanGetDetectedDevices()
{
timestamp -= (timestamp % 30000); // same TimeInterval used in controller
var detectedDevice = new DetectedDevice
{
DeviceX = 50,
DeviceY = 70,
Timestamp = timestamp,
VenueID = 1
};

await _client.PostAsJsonAsync("/api/DetectedDevices", detectedDevice);

var response = await _client.GetAsync("/api/DetectedDevices");
response.EnsureSuccessStatusCode();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,83 +21,24 @@ public RaspDataIntegrationTests(CustomWebApplicationFactory factory)

}

/// <summary>
/// testing post endpoint for RaspData
/// </summary>
/// <remark>
/// Expected to pass by checking the response code
/// Also if the returned MacAddress is the same as expected
/// </remark>
[Fact]
public async Task PostRaspData_SavesRaspData_ReturnsCreated()
{
// Arrange: Create a Venue object to send to the API
var RaspData = new RaspData { MacAddress = "24:58:46:97:75:3F", RaspId = 3, Rssi = -82, UnixTimestamp = 1746530400000 };

// Act: Send the POST request to the /api/Venue endpoint
var response = await _client.PostAsJsonAsync("/api/RaspData", RaspData);

// Assert: Ensure the response status code is 201 (Created)
response.EnsureSuccessStatusCode();

// Deserialize the returned content to check the saved venue
var returned = await response.Content.ReadFromJsonAsync<RaspData>();

// Assert: Check if the returned venue is as expected
Assert.Equal("24:58:46:97:75:3F", returned.MacAddress);
}

/*
[Fact]
public async Task GetVenue__ReturnsVenue()
{
// Arrange
const int id = 4;
var response = await _client.GetAsync($"/api/Venue/{id}");
response.EnsureSuccessStatusCode();
var returned = await response.Content.ReadFromJsonAsync<Venue>();

// Assert
Assert.Equal(id, returned.VenueID);
Assert.Equal("TestVenue", returned.VenueName);
}

[Fact]
public async Task GetVenue_UpdateVenue_ReturnsUpdatedVenue()
{
// Arrange
const int id = 4;
var getResponse = await _client.GetAsync($"/api/Venue/{id}");
getResponse.EnsureSuccessStatusCode();
var originalVenue = await getResponse.Content.ReadFromJsonAsync<Venue>();

Assert.NotNull(originalVenue);

// Act - Modify the venue
originalVenue.VenueName = "Updated Venue Name";

var putResponse = await _client.PutAsJsonAsync($"/api/Venue/{id}", originalVenue);
putResponse.EnsureSuccessStatusCode();

// Assert - Get again and verify the updated name
var confirmResponse = await _client.GetAsync($"/api/Venue/{id}");
confirmResponse.EnsureSuccessStatusCode();
var updatedVenue = await confirmResponse.Content.ReadFromJsonAsync<Venue>();

Assert.Equal("Updated Venue Name", updatedVenue.VenueName);
}

[Fact]
public async Task DeleteVenue_ReturnsDeletedVenue_And_CannotBeFoundAfter()
{
// Arrange
var venue = new Venue { VenueID = 99, VenueName = "Venue to Delete" };
var postResponse = await _client.PostAsJsonAsync("/api/Venue", venue);
postResponse.EnsureSuccessStatusCode();

// Act
var deleteResponse = await _client.DeleteAsync($"/api/Venue/{venue.VenueID}");

// Assert
Assert.Equal(HttpStatusCode.NoContent, deleteResponse.StatusCode);

var getAfterDelete = await _client.GetAsync($"/api/Venue/{venue.VenueID}");
Assert.Equal(HttpStatusCode.NotFound, getAfterDelete.StatusCode);
}
*/

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,43 +20,65 @@ public VenueIntegrationTests(CustomWebApplicationFactory factory)
_client = _factory.CreateClient();
}

/// <summary>
/// Testing our endpoint for posting a Venue
/// </summary>
/// <remark>
/// Expected to pass by checking the response code
/// Also if the returned name is the same as expected
/// </remark>
[Fact]
public async Task PostVenue_SavesVenue_ReturnsCreated()
{
// Arrange: Create a Venue object to send to the API
var venue = new Venue { VenueID = 4, VenueName = "TestVenue" };
var venue = new Venue { VenueID = 5, VenueName = "TestVenue" };

// Act: Send the POST request to the /api/Venue endpoint
var response = await _client.PostAsJsonAsync("/api/Venue", venue);

response.EnsureSuccessStatusCode();
// Deserialize the returned content to check the saved venue
var returned = await response.Content.ReadFromJsonAsync<Venue>();

// Assert: Check if the returned venue is as expected
Assert.Equal("TestVenue", returned.VenueName);
}

/// <summary>
/// testing get endpoint for getting a Venue
/// </summary>
/// <remark>
/// Expected to pass by checking the response code
/// Also if the returned name and Id is the same as expected
/// </remark>
[Fact]
public async Task GetVenue__ReturnsVenue()
{
// Arrange
const int id = 4;
var response = await _client.GetAsync($"/api/Venue/{id}");

response.EnsureSuccessStatusCode();
var returned = await response.Content.ReadFromJsonAsync<Venue>();

// Assert
Assert.Equal(id, returned.VenueID);
Assert.Equal("TestVenue", returned.VenueName);
Assert.Equal("Test Venue", returned.VenueName);
}

/// <summary>
/// Testing the put endpoint by first getting a Venue
/// Then use the enpoint to update its name
/// </summary>
/// <remark>
/// Expected to pass by checking the response code
/// Also if the returned name is updated as we expected
/// </remark>
[Fact]
public async Task GetVenue_UpdateVenue_ReturnsUpdatedVenue()
{
// Arrange
const int id = 4;
var getResponse = await _client.GetAsync($"/api/Venue/{id}");

getResponse.EnsureSuccessStatusCode();
var originalVenue = await getResponse.Content.ReadFromJsonAsync<Venue>();

Assert.NotNull(originalVenue);
Expand All @@ -65,7 +87,7 @@ public async Task GetVenue_UpdateVenue_ReturnsUpdatedVenue()
originalVenue.VenueName = "Updated Venue Name";

var putResponse = await _client.PutAsJsonAsync($"/api/Venue/{id}", originalVenue);

putResponse.EnsureSuccessStatusCode();

// Assert - Get again and verify the updated name
var confirmResponse = await _client.GetAsync($"/api/Venue/{id}");
Expand All @@ -75,21 +97,23 @@ public async Task GetVenue_UpdateVenue_ReturnsUpdatedVenue()
Assert.Equal("Updated Venue Name", updatedVenue.VenueName);
}

/// <summary>
/// testing delete endpoint
/// </summary>
/// <remark>
/// Expected to pass by checking the response code
/// Also if the Venue can not be found after deletion
/// </remark>
[Fact]
public async Task DeleteVenue_ReturnsDeletedVenue_And_CannotBeFoundAfter()
{
// Arrange
var venue = new Venue { VenueID = 99, VenueName = "Venue to Delete" };
var postResponse = await _client.PostAsJsonAsync("/api/Venue", venue);


// Act
var deleteResponse = await _client.DeleteAsync($"/api/Venue/{venue.VenueID}");
var deleteResponse = await _client.DeleteAsync("/api/Venue/99");

// Assert
Assert.Equal(HttpStatusCode.NoContent, deleteResponse.StatusCode);

var getAfterDelete = await _client.GetAsync($"/api/Venue/{venue.VenueID}");
var getAfterDelete = await _client.GetAsync("/api/Venue/99");
Assert.Equal(HttpStatusCode.NotFound, getAfterDelete.StatusCode);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,20 +27,22 @@
var scope = factory.Services.CreateScope();
_context = scope.ServiceProvider.GetRequiredService<MyDbContext>();
_circleUtils = scope.ServiceProvider.GetRequiredService<CircleUtils>(); // Ensure CircleUtils is injected
_helper = new DetectedDeviceHelper(_context, _circleUtils, null); // Ensure DetectedDeviceHelper is injected

Check warning on line 30 in CrowdedBackend/CrowdedBackend.Tests/IntegrationTests/Helpers/DetectedDeviceHelperTest.cs

View workflow job for this annotation

GitHub Actions / format-check

Cannot convert null literal to non-nullable reference type.
}

/// <summary>
/// Testing the DetectedDeviceHelper that sorts in our raspData and removes duplicates
/// Using raspOutputData.json which is a dummy data file.
/// </summary>
/// <remark>
/// Expected to pass by checking if the result is not null. The result is raspData
/// </remark>
[Fact]
public async Task HandleRaspPostRequest_test()
{

// Arrange
var now = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
// Adding Raspberry Pi devices to the database
_context.RaspberryPi.Add(new RaspberryPi { VenueID = 10, RaspX = 50, RaspY = 60 });
_context.RaspberryPi.Add(new RaspberryPi { VenueID = 10, RaspX = 90, RaspY = 100 });
_context.RaspberryPi.Add(new RaspberryPi { VenueID = 10, RaspX = 50, RaspY = 30 });
await _context.SaveChangesAsync(); // Don't forget to save changes!

// Read the raspOutputData from the JSON file
// Arrange
Expand Down
Loading
Loading