Skip to content

Commit

Permalink
add test for Conversation class
Browse files Browse the repository at this point in the history
  • Loading branch information
AlexNi245 committed Nov 19, 2024
1 parent 7ef92a3 commit dc84d86
Show file tree
Hide file tree
Showing 7 changed files with 75 additions and 34 deletions.
6 changes: 3 additions & 3 deletions packages/js-sdk/src/Dm3.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import { Conversations } from './conversation/Conversations';
import { Tld } from './tld/Tld';
import { ITLDResolver } from './tld/nameService/ITLDResolver';

export class Dm3 {
public readonly conversations: Conversations;
public readonly tld: Tld;
public readonly tld: ITLDResolver;

constructor(conversations: Conversations, tld: Tld) {
constructor(conversations: Conversations, tld: ITLDResolver) {
this.conversations = conversations;
this.tld = tld;
}
Expand Down
28 changes: 21 additions & 7 deletions packages/js-sdk/src/Dm3Sdk.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,11 @@ import { Dm3Sdk, Dm3SdkConfig } from './Dm3Sdk';

import MockAdapter from 'axios-mock-adapter';
import { normalizeEnsName } from '@dm3-org/dm3-lib-profile';
import { ITLDResolver } from './tld/nameService/ITLDResolver';

describe('Dm3Sdk', () => {
let alice: MockedUserProfile;
let bob: MockedUserProfile;

//Axios mock to mock the http requests
let axiosMock;
Expand All @@ -22,9 +24,12 @@ describe('Dm3Sdk', () => {
'alice.up',
['test.io'],
);
bob = await mockUserProfile(ethers.Wallet.createRandom(), 'bob.up', [
'test.io',
]);
});

it('test', async () => {
it('can add a conversaton to the contact list', async () => {
axiosMock = new MockAdapter(axios);
//Mock BackendConnector HttpRequests
//Mock profileExistsOnDeliveryService
Expand Down Expand Up @@ -52,15 +57,24 @@ describe('Dm3Sdk', () => {
)
.reply(200, 'mock-challenge');

const mockTldResolver = {
resolveTLDtoAlias: async () =>
`${normalizeEnsName(bob.address)}.addr.test`,
resolveAliasToTLD: async () => 'bob.eth',
} as unknown as ITLDResolver;

const mockConfig: Dm3SdkConfig = {
mainnetProvider: {} as ethers.providers.JsonRpcProvider,
storageApi: {} as StorageAPI,
storageApi: {
addConversation: async () => {},
} as unknown as StorageAPI,
nonce: '1',
defaultDeliveryService: 'test.io',
addressEnsSubdomain: '.addr.test',
userEnsSubdomain: '.user.test',
resolverBackendUrl: 'resolver.io',
backendUrl: 'http://localhost:4060',
_tld: mockTldResolver,
};

const dm3 = await new Dm3Sdk(mockConfig).login({
Expand All @@ -69,10 +83,10 @@ describe('Dm3Sdk', () => {
accountAddress: alice.address,
});

console.log(dm3.conversations.conversations);

/* await dm3.conversations.addConversation('karl.eth');
const c = dm3.conversations.conversations;
const karl = c[0]; */
await dm3.conversations.addConversation('bob.eth');
const c = dm3.conversations.list;
console.log(c);
expect(c.length).toBe(1);
expect(c[0].contact.name).toBe('bob.eth');
});
});
23 changes: 16 additions & 7 deletions packages/js-sdk/src/Dm3Sdk.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import { StorageAPI } from '@dm3-org/dm3-lib-storage';
import { ethers } from 'ethers';
import { Tld } from './tld/Tld';
import { Dm3 } from './Dm3';
import { ITLDResolver } from './tld/nameService/ITLDResolver';

/**
* DM3SDK
Expand All @@ -36,7 +37,7 @@ export interface Dm3SdkConfig {
userEnsSubdomain: string;
resolverBackendUrl: string;
backendUrl: string;
lukso?: ethers.providers.ExternalProvider;
_tld?: ITLDResolver;
}

export class Dm3Sdk {
Expand Down Expand Up @@ -69,6 +70,11 @@ export class Dm3Sdk {
*/
public conversations: Conversations;

/**
* DM3 TLD
*/
private _tld?: ITLDResolver;

constructor(config: Dm3SdkConfig) {
//TODO keep ethers v5 for know but extract into common interface later
this.mainnetProvider = config.mainnetProvider;
Expand All @@ -80,6 +86,7 @@ export class Dm3Sdk {
this.resolverBackendUrl = config.resolverBackendUrl;
this.backendUrl = config.backendUrl;
this.storageApi = config.storageApi;
this._tld = config._tld;
}
/**
* login can be used to login with a profile regardles the connector. Its also great for testing
Expand All @@ -93,12 +100,14 @@ export class Dm3Sdk {
profile: SignedUserProfile;
accountAddress: string;
}) {
const tld = new Tld(
this.mainnetProvider,
this.addressEnsSubdomain,
this.userEnsSubdomain,
this.resolverBackendUrl,
);
const tld =
this._tld ??
new Tld(
this.mainnetProvider,
this.addressEnsSubdomain,
this.userEnsSubdomain,
this.resolverBackendUrl,
);

this.profileKeys = profileKeys;
this.profile = profile;
Expand Down
31 changes: 19 additions & 12 deletions packages/js-sdk/src/conversation/Conversations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,19 +13,20 @@ import { Contact, Conversation, getEmptyContact } from './types';
import { Tld } from '../tld/Tld';
import { hydrateContract as hydrateContact } from './hydrate/hydrateContact';
import { ethers } from 'ethers';
import { ITLDResolver } from '../tld/nameService/ITLDResolver';

export class Conversations {
private readonly provider: ethers.providers.JsonRpcProvider;
private readonly storageApi: StorageAPI;
private readonly tld: Tld;
private readonly tld: ITLDResolver;
private readonly addressEnsSubdomain: string;
private readonly account: Account;

public conversations: Conversation[];
public list: Conversation[];

constructor(
storageApi: StorageAPI,
tld: Tld,
tld: ITLDResolver,
mainnetProvider: ethers.providers.JsonRpcProvider,
account: Account,
addressEnsSubdomain: string,
Expand All @@ -35,7 +36,7 @@ export class Conversations {
this.account = account;
this.provider = mainnetProvider;
this.addressEnsSubdomain = addressEnsSubdomain;
this.conversations = [];
this.list = [];
}

public async addConversation(_ensName: string) {
Expand All @@ -49,6 +50,7 @@ export class Conversations {
updatedAt: new Date().getTime(),
previewMessage: undefined,
};

const conversationPreview = this._addConversation(newConversation);
//Add the contact to the storage in the background
this.storageApi.addConversation(aliasName, [contactTldName]);
Expand All @@ -64,7 +66,7 @@ export class Conversations {
if (isOwnContact) {
return;
}
const alreadyAddedContact = this.conversations.find(
const alreadyAddedContact = this.list.find(
(existingContact) =>
existingContact.contact.account.ensName === ensName,
);
Expand Down Expand Up @@ -101,16 +103,21 @@ export class Conversations {
const hydratedContact = await hydrateContact(
this.provider,
conversation,
this.tld.resolveTLDtoAlias,
this.tld.resolveAliasToTLD,
this.addressEnsSubdomain,
);

const hydratedConversation: Conversation = {
messages: undefined as any,
contact: hydratedContact,
};
this.conversations.push(hydratedConversation);

//find existing contact and replace it with the hydrated one
this.list = this.list.map((existingContact) => {
if (existingContact.contact.account.ensName === ensName) {
return hydratedConversation;
}
return existingContact;
});
//Return the new onhydrated contact
return hydratedConversation;
}
Expand All @@ -126,14 +133,14 @@ export class Conversations {
const hydratedContact = await hydrateContact(
this.provider,
conversation,
this.tld.resolveTLDtoAlias,
this.tld.resolveAliasToTLD,
this.addressEnsSubdomain,
);
const hydratedConversation: Conversation = {
messages: undefined as any,
contact: hydratedContact,
};
this.conversations.push(hydratedConversation);
this.list.push(hydratedConversation);

return hydratedConversation;
};
Expand All @@ -142,12 +149,12 @@ export class Conversations {
//Dont add duplicates
const uniqueContacts = newConversations.filter(
(newContact) =>
!this.conversations.some(
!this.list.some(
(existingContact) =>
existingContact.contact.account.ensName ===
newContact.contact.account.ensName,
),
);
this.conversations = [...this.conversations, ...uniqueContacts];
this.list = [...this.list, ...uniqueContacts];
}
}
4 changes: 2 additions & 2 deletions packages/js-sdk/src/conversation/hydrate/fetchDsProfiles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,9 @@ export const fetchDsProfiles = async (
): Promise<FetchDsProfilesResult> => {
const deliveryServiceEnsNames = account.profile?.deliveryServices ?? [];
if (deliveryServiceEnsNames.length === 0) {
//If there is nop DS profile the message will be storaged at the client side until they recipient has createed an account
//If there is no DS profile the message will be stored at the client side until the recipient has created an account
console.debug(
'[fetchDeliverServicePorfile] Cant resolve deliveryServiceEnsName',
'[fetchDeliveryServiceProfile] account has no delivery-service profile',
);
return {
account,
Expand Down
4 changes: 2 additions & 2 deletions packages/js-sdk/src/message/Messages.ts
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ export class Messages {
}

//Find the recipient of the message in the contact list
const recipient = this.conversations.conversations.find(
const recipient = this.conversations.list.find(
(c) => c.contact.account.ensName === contact,
);
/**
Expand All @@ -99,7 +99,7 @@ export class Messages {
//There are cases were a messages is already to be send even though the contract hydration is not finished yet.
//This happens if a message has been picked up from the delivery service and the clients sends READ_RECEIVE or READ_OPENED acknowledgements
//In that case we've to check again to the if the user is a DM3 user, before we decide to keep the message
const potentialReceiver = this.conversations.conversations.find(
const potentialReceiver = this.conversations.list.find(
(c) => c.contact.account.ensName === contact,
);

Expand Down
13 changes: 12 additions & 1 deletion packages/js-sdk/src/tld/Tld.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ const SUPPORTED_NAMESERVICES = (
new EthAddressResolver(addressEnsSubdomain),
];

export class Tld {
export class Tld implements ITLDResolver {
private aliasTldCache: { [ensName: string]: string };
private tldAliasCache: { [ensName: string]: string };
private readonly mainnetProvider: ethers.providers.JsonRpcProvider;
Expand All @@ -48,6 +48,17 @@ export class Tld {
this.userEnsSubdomain = userEnsSubdomain;
this.resolverBackendUrl = resolverBackendUrl;
}
isResolverForTldName(ensName: string): Promise<boolean> {
//Since its the root resolver its always capable of resolving
return Promise.resolve(true);
}
isResolverForAliasName(
ensName: string,
foreignTldName?: string,
): Promise<boolean> {
//Since its the root resolver its always capable of resolving
return Promise.resolve(true);
}
//e.g. 0x1234.gnosis.eth -> 0x1234.gno
resolveAliasToTLD = async (ensName: string, foreignTldName?: string) => {
if (this.aliasTldCache[ensName]) {
Expand Down

0 comments on commit dc84d86

Please sign in to comment.