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

fix: rename to didcore and fix failing http tests #47

Merged
merged 1 commit into from
Feb 13, 2024
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
2 changes: 1 addition & 1 deletion packages/web5/lib/src/dids.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
export './dids/did.dart';
export './dids/did_uri.dart';
export './dids/data_models.dart';
export 'dids/did_core.dart';
export './dids/did_resolver.dart';
export './dids/did_dht/did_dht.dart';
export './dids/did_jwk/did_jwk.dart';
Expand Down
11 changes: 0 additions & 11 deletions packages/web5/lib/src/dids/data_models.dart

This file was deleted.

11 changes: 11 additions & 0 deletions packages/web5/lib/src/dids/did_core.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
export 'did_core/did_service.dart';
export 'did_core/did_resource.dart';
export 'did_core/did_document.dart';
export 'did_core/did_resolution_result.dart';
export 'did_core/did_dereference_result.dart';
export 'did_core/did_verification_method.dart';
export 'did_core/did_resolution_metadata.dart';
export 'did_core/did_dereference_options.dart';
export 'did_core/did_dereference_metadata.dart';
export 'did_core/did_document_metadata.dart';
export 'did_core/did_verification_relationship.dart';
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import 'dart:convert';

import 'package:web5/src/dids/structures/did_dereference_metadata.dart';
import 'package:web5/src/dids/structures/did_document_metadata.dart';
import 'package:web5/src/dids/structures/did_resource.dart';
import 'package:web5/src/dids/did_core/did_dereference_metadata.dart';
import 'package:web5/src/dids/did_core/did_document_metadata.dart';
import 'package:web5/src/dids/did_core/did_resource.dart';

class DidDereferenceResult {
DidDereferenceMetadata dereferencingMetadata;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import 'package:collection/collection.dart';
import 'package:web5/src/dids/structures/did_service.dart';
import 'package:web5/src/dids/structures/did_resource.dart';
import 'package:web5/src/dids/structures/did_verification_method.dart';
import 'package:web5/src/dids/structures/did_verification_relationship.dart';
import 'package:web5/src/dids/did_core/did_service.dart';
import 'package:web5/src/dids/did_core/did_resource.dart';
import 'package:web5/src/dids/did_core/did_verification_method.dart';
import 'package:web5/src/dids/did_core/did_verification_relationship.dart';

/// A set of data describing the DID subject including mechanisms such as:
/// * cryptographic public keys - used to authenticate itself and prove
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,4 +78,33 @@ class DidDocumentMetadata {

return json;
}

@override
bool operator ==(Object other) {
if (identical(this, other)) return true;

return other is DidDocumentMetadata &&
other.created == created &&
other.updated == updated &&
other.deactivated == deactivated &&
other.versionId == versionId &&
other.nextUpdate == nextUpdate &&
other.nextVersionId == nextVersionId &&
other.equivalentId == equivalentId &&
other.canonicalId == canonicalId;
}

@override
int get hashCode {
return Object.hash(
created,
updated,
deactivated,
versionId,
nextUpdate,
nextVersionId,
equivalentId,
canonicalId,
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -36,4 +36,16 @@ class DidResolutionMetadata {

return json;
}

@override
bool operator ==(Object other) {
if (identical(this, other)) return true;

return other is DidResolutionMetadata &&
other.contentType == contentType &&
other.error == error;
}

@override
int get hashCode => Object.hash(contentType, error);
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import 'package:web5/src/dids/structures/did_document.dart';
import 'package:web5/src/dids/structures/did_document_metadata.dart';
import 'package:web5/src/dids/structures/did_resolution_metadata.dart';
import 'package:web5/src/dids/did_core/did_document.dart';
import 'package:web5/src/dids/did_core/did_document_metadata.dart';
import 'package:web5/src/dids/did_core/did_resolution_metadata.dart';

/// A class representing the result of a DID (Decentralized Identifier)
/// resolution.
Expand Down Expand Up @@ -86,4 +86,23 @@ class DidResolutionResult {
bool hasError() {
return didResolutionMetadata.error != null;
}

@override
bool operator ==(Object other) {
if (identical(this, other)) return true;

return other is DidResolutionResult &&
other.didResolutionMetadata == didResolutionMetadata &&
other.didDocument == didDocument &&
other.didDocumentMetadata == didDocumentMetadata;
}

@override
int get hashCode {
return Object.hash(
didResolutionMetadata,
didDocument,
didDocumentMetadata,
);
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import 'package:web5/src/dids/structures/did_resource.dart';
import 'package:web5/src/dids/did_core/did_resource.dart';

/// Services are used in DID documents to express ways of communicating with
/// the DID subject or associated entities.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import 'package:web5/src/crypto.dart';
import 'package:web5/src/dids/structures/did_resource.dart';
import 'package:web5/src/dids/did_core/did_resource.dart';

/// A DID document can express verification methods, such as cryptographic
/// public keys, which can be used to authenticate or authorize interactions
Expand Down
2 changes: 1 addition & 1 deletion packages/web5/lib/src/dids/did_dht/did_dht.dart
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import 'package:web5/src/crypto.dart';
import 'package:web5/src/dids/did.dart';
import 'package:web5/src/extensions.dart';
import 'package:web5/src/dids/did_uri.dart';
import 'package:web5/src/dids/data_models.dart';
import 'package:web5/src/dids/did_core.dart';
import 'package:web5/src/dids/did_dht/dns_packet.dart';
import 'package:web5/src/dids/did_method_resolver.dart';

Expand Down
2 changes: 1 addition & 1 deletion packages/web5/lib/src/dids/did_jwk/did_jwk.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import 'package:web5/src/crypto.dart';
import 'package:web5/src/dids/did.dart';
import 'package:web5/src/extensions.dart';
import 'package:web5/src/dids/did_uri.dart';
import 'package:web5/src/dids/data_models.dart';
import 'package:web5/src/dids/did_core.dart';
import 'package:web5/src/dids/did_method_resolver.dart';

final base64UrlEncoder = Base64Codec.urlSafe().encoder;
Expand Down
2 changes: 1 addition & 1 deletion packages/web5/lib/src/dids/did_method_resolver.dart
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import 'package:web5/src/dids/data_models.dart';
import 'package:web5/src/dids/did_core.dart';

/// Represents a method resolver for a specific DID method.
class DidMethodResolver {
Expand Down
2 changes: 1 addition & 1 deletion packages/web5/lib/src/dids/did_resolver.dart
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import 'package:web5/src/dids/did_uri.dart';
import 'package:web5/src/dids/data_models.dart';
import 'package:web5/src/dids/did_core.dart';
import 'package:web5/src/dids/did_method_resolver.dart';

/// A resolver for Decentralized Identifiers (DIDs).
Expand Down
9 changes: 6 additions & 3 deletions packages/web5/lib/src/dids/did_web/did_web.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import 'dart:convert';
import 'dart:io';

import 'package:web5/src/crypto/key_manager.dart';
import 'package:web5/src/dids/data_models.dart';
import 'package:web5/src/dids/did_core.dart';
import 'package:web5/src/dids/did.dart';
import 'package:web5/src/dids/did_method_resolver.dart';
import 'package:web5/src/dids/did_uri.dart';
Expand All @@ -20,7 +20,10 @@ class DidWeb implements Did {

static final resolver = DidMethodResolver(name: methodName, resolve: resolve);

static Future<DidResolutionResult> resolve(String didUri) async {
static Future<DidResolutionResult> resolve(
String didUri, {
HttpClient? client,
}) async {
final DidUri parsedDidUri;

try {
Expand Down Expand Up @@ -48,7 +51,7 @@ class DidWeb implements Did {
resolutionUrl = Uri.decodeFull('$resolutionUrl/did.json');
final parsedUrl = Uri.parse(resolutionUrl);

final httpClient = HttpClient();
final httpClient = client ??= HttpClient();
final request = await httpClient.getUrl(parsedUrl);
final response = await request.close();

Expand Down
1 change: 1 addition & 0 deletions packages/web5/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,5 @@ dependencies:

dev_dependencies:
lints: ^3.0.0
mocktail: ^1.0.3
test: ^1.21.0
138 changes: 133 additions & 5 deletions packages/web5/test/dids/did_web_test.dart
Original file line number Diff line number Diff line change
@@ -1,20 +1,148 @@
import 'dart:convert';
import 'dart:io';

import 'package:mocktail/mocktail.dart';
import 'package:test/test.dart';
import 'package:web5/src/dids/did_core/did_resolution_result.dart';
import 'package:web5/src/dids/did_web/did_web.dart';

class MockHttpClient extends Mock implements HttpClient {}

class MockHttpRequest extends Mock implements HttpClientRequest {}

class MockHttpResponse extends Mock implements HttpClientResponse {}

const validDidWebDocument = '''{
"id": "did:web:www.linkedin.com",
"@context": [
"https://www.w3.org/ns/did/v1",
{
"@base": "did:web:www.linkedin.com"
}
],
"service": [
{
"id": "#linkeddomains",
"type": "LinkedDomains",
"serviceEndpoint": {
"origins": [
"https://www.linkedin.com/"
]
}
},
{
"id": "#hub",
"type": "IdentityHub",
"serviceEndpoint": {
"instances": [
"https://hub.did.msidentity.com/v1.0/658728e7-1632-412a-9815-fe53f53ec58b"
]
}
}
],
"verificationMethod": [
{
"id": "#074cfbf193f046bcba5841ac4751e91bvcSigningKey-46682",
"controller": "did:web:www.linkedin.com",
"type": "EcdsaSecp256k1VerificationKey2019",
"publicKeyJwk": {
"crv": "secp256k1",
"kty": "EC",
"x": "NHIQivVR0HX7c0flpxgWQ7vRtbWDvr0UPN1nJ--0lyU",
"y": "hYiIldgLRShym7vzflFrEkg6NYkayUHkDpV0RMjUEYE"
}
}
],
"authentication": [
"#074cfbf193f046bcba5841ac4751e91bvcSigningKey-46682"
],
"assertionMethod": [
"#074cfbf193f046bcba5841ac4751e91bvcSigningKey-46682"
]
}''';

void main() {
final MockHttpClient mockClient = MockHttpClient();
final MockHttpRequest request = MockHttpRequest();
final MockHttpResponse response = MockHttpResponse();

setUpAll(() {
registerFallbackValue(Uri());
});

setUp(() {
reset(mockClient);
reset(request);
reset(response);
});

group('DidWeb', () {
test('should return invalid did with bad data', () async {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mistermoe you might want to check that these tests actually make sense :)

final result = await DidWeb.resolve('bogus');
expect(result, DidResolutionResult.invalidDid());
});

test('should return invalid did with wrong method', () async {
final result = await DidWeb.resolve('did:bad:www.linkedin.com');
expect(result, DidResolutionResult.invalidDid());
});

test('should return invalid did with failed http request', () async {
when(() => response.statusCode).thenReturn(400);
when(() => request.close()).thenAnswer((_) async => response);
when(() => mockClient.getUrl(any())).thenAnswer((_) async => request);

final result = await DidWeb.resolve(
'did:web:www.linkedin.com',
client: mockClient,
);
expect(result, DidResolutionResult.invalidDid());
});

test('should resolve successfully', () async {
final result = await DidWeb.resolve('did:web:www.linkedin.com');
expect(result.didDocument, isNotNull);
when(() => response.statusCode).thenReturn(200);
when(() => response.transform(utf8.decoder))
.thenAnswer((_) => Stream.value(validDidWebDocument));
when(() => request.close()).thenAnswer((_) async => response);
when(
() => mockClient.getUrl(
Uri.parse('https://www.linkedin.com/.well-known/did.json'),
),
).thenAnswer((_) async => request);

final result =
await DidWeb.resolve('did:web:www.linkedin.com', client: mockClient);

expect(result.didDocument, isNotNull);
expect('did:web:www.linkedin.com', result.didDocument!.id);

verify(
() => mockClient
.getUrl(Uri.parse('https://www.linkedin.com/.well-known/did.json')),
);
});

test('should resolve with paths', () async {
final result = await DidWeb.resolve('did:web:localhost%3A8892:ingress');
test('should resolve successfully with paths', () async {
when(() => response.statusCode).thenReturn(200);
when(() => response.transform(utf8.decoder))
.thenAnswer((_) => Stream.value(validDidWebDocument));
when(() => request.close()).thenAnswer((_) async => response);
when(
() => mockClient.getUrl(
Uri.parse('http://localhost:8892/ingress/did.json'),
),
).thenAnswer((_) async => request);

final result = await DidWeb.resolve(
'did:web:localhost%3A8892:ingress',
client: mockClient,
);
expect(result.didDocument, isNotNull);

expect('did:web:localhost%3A8892:ingress', result.didDocument!.id);
verify(
() => mockClient
.getUrl(Uri.parse('http://localhost:8892/ingress/did.json')),
);
});
});
}
Loading