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
33 changes: 33 additions & 0 deletions lib/src/adapter/connection_info.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import 'package:meta/meta.dart';

import '../ip_address/ip_address.dart';

/// Represents the connection information of a network request.
/// Can be HTTP but also other types of network connections.
@immutable
class ConnectionInfo {
/// The internet address of the connected client.
final IPAddress remoteAddress;

/// The remote network port of the connected client.
final int remotePort;

/// The local network port of the client connection.
final int localPort;

/// Creates a [ConnectionInfo] object.
const ConnectionInfo({
required this.remoteAddress,
required this.remotePort,
required this.localPort,
});

/// A [ConnectionInfo] object representing an unknown connection.
ConnectionInfo.unknown()
: this(remoteAddress: IPv6Address.any, remotePort: 0, localPort: 0);

@override
String toString() {
return 'ConnectionInfo(remote: ${remoteAddress is IPv6Address ? '[$remoteAddress]' : remoteAddress}:$remotePort, local port:$localPort)';
}
}
91 changes: 91 additions & 0 deletions test/adapter/connection_info_test.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
import 'package:relic/src/adapter/connection_info.dart';
import 'package:relic/src/ip_address/ip_address.dart';
import 'package:test/test.dart';

void main() {
group('ConnectionInfo', () {
group('Constructor', () {
test('Given valid remote address, remote port, and local port, '
'when a ConnectionInfo object is created, '
'then its properties are set correctly.', () {
// Arrange
final remoteAddress = IPAddress.parse('192.168.1.100');
const remotePort = 12345;
const localPort = 8080;

// Act
final connectionInfo = ConnectionInfo(
remoteAddress: remoteAddress,
remotePort: remotePort,
localPort: localPort,
);

// Assert
expect(connectionInfo.remoteAddress, equals(remoteAddress));
expect(connectionInfo.remotePort, equals(remotePort));
expect(connectionInfo.localPort, equals(localPort));
});
});

group('Static ConnectionInfo.unknown()', () {
test('Given ConnectionInfo.unknown(), '
'when its properties are accessed, '
'then they match the expected default values.', () {
// Act
final unknownInfo = ConnectionInfo.unknown();

// Assert
expect(unknownInfo.remoteAddress, equals(IPv6Address.any));
expect(unknownInfo.remotePort, equals(0));
expect(unknownInfo.localPort, equals(0));
});
});

group('toString() method', () {
test('Given a ConnectionInfo object, '
'when toString() is called, '
'then it returns the correctly formatted string.', () {
// Arrange
final connectionInfo = ConnectionInfo(
remoteAddress: IPAddress.parse('10.0.0.5'),
remotePort: 54321,
localPort: 9000,
);
const expectedString =
'ConnectionInfo(remote: 10.0.0.5:54321, local port:9000)';

// Act

// Assert
expect(connectionInfo.toString(), equals(expectedString));
});

test('Given a ConnectionInfo object with IPv6 address, '
'when toString() is called, '
'then it returns the correctly formatted string with brackets.', () {
// Arrange
final connectionInfo = ConnectionInfo(
remoteAddress: IPAddress.parse('2001:db8::1'),
remotePort: 443,
localPort: 8080,
);
const expectedString =
'ConnectionInfo(remote: [2001:db8::1]:443, local port:8080)';

// Act & Assert
expect(connectionInfo.toString(), equals(expectedString));
});

test('Given ConnectionInfo.unknown(), '
'when toString() is called, '
'then it returns the correctly formatted string for empty.', () {
// Arrange
final emptyInfo = ConnectionInfo.unknown();
const expectedString = 'ConnectionInfo(remote: [::]:0, local port:0)';

// Act & Assert
expect(emptyInfo.toString(), equals(expectedString));
});
});
});
}
Loading