mirror of
https://github.com/haveno-dex/haveno-ts.git
synced 2025-02-03 01:49:54 -05:00
Add API functions to support trade chat (#75)
This commit is contained in:
parent
7ddf429fc7
commit
3024c5b2fc
@ -880,6 +880,9 @@ test("Can complete a trade", async () => {
|
|||||||
fetchedTrade = await alice.getTrade(trade.getTradeId());
|
fetchedTrade = await alice.getTrade(trade.getTradeId());
|
||||||
expect(fetchedTrade.getPhase()).toEqual("DEPOSIT_PUBLISHED");
|
expect(fetchedTrade.getPhase()).toEqual("DEPOSIT_PUBLISHED");
|
||||||
|
|
||||||
|
// test trader chat
|
||||||
|
await testTradeChat(trade.getTradeId(), alice, bob);
|
||||||
|
|
||||||
// mine until deposit txs unlock
|
// mine until deposit txs unlock
|
||||||
HavenoUtils.log(1, "Mining to unlock deposit txs");
|
HavenoUtils.log(1, "Mining to unlock deposit txs");
|
||||||
await waitForUnlockedTxs(fetchedTrade.getMakerDepositTxId(), fetchedTrade.getTakerDepositTxId());
|
await waitForUnlockedTxs(fetchedTrade.getMakerDepositTxId(), fetchedTrade.getTakerDepositTxId());
|
||||||
@ -1780,3 +1783,81 @@ function testOffer(offer: OfferInfo, config?: any) {
|
|||||||
}
|
}
|
||||||
// TODO: test rest of offer
|
// TODO: test rest of offer
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests trade chat functionality. Must be called during an open trade.
|
||||||
|
*/
|
||||||
|
async function testTradeChat(tradeId: string, alice: HavenoDaemon, bob: HavenoDaemon) {
|
||||||
|
HavenoUtils.log(1, "Testing trade chat");
|
||||||
|
|
||||||
|
// invalid trade should throw error
|
||||||
|
try {
|
||||||
|
await alice.getChatMessages("invalid");
|
||||||
|
throw new Error("get chat messages with invalid id should fail");
|
||||||
|
} catch (err) {
|
||||||
|
assert.equal(err.message, "trade with id 'invalid' not found");
|
||||||
|
}
|
||||||
|
|
||||||
|
// trade chat should be in initial state
|
||||||
|
let messages = await alice.getChatMessages(tradeId);
|
||||||
|
assert(messages.length == 0);
|
||||||
|
messages = await bob.getChatMessages(tradeId);
|
||||||
|
assert(messages.length == 0);
|
||||||
|
|
||||||
|
// add notification handlers and send some messages
|
||||||
|
let aliceNotifications: NotificationMessage[] = [];
|
||||||
|
let bobNotifications: NotificationMessage[] = [];
|
||||||
|
await alice.addNotificationListener(notification => { aliceNotifications.push(notification); });
|
||||||
|
await bob.addNotificationListener(notification => { bobNotifications.push(notification); });
|
||||||
|
|
||||||
|
// send simple conversation and verify the list of messages
|
||||||
|
let aliceMsg = "Hi I'm Alice";
|
||||||
|
await alice.sendChatMessage(tradeId, aliceMsg);
|
||||||
|
await wait(TestConfig.maxTimePeerNoticeMs);
|
||||||
|
messages = await bob.getChatMessages(tradeId);
|
||||||
|
expect(messages.length).toEqual(2);
|
||||||
|
expect(messages[0].getIsSystemMessage()).toEqual(true); // first message is system
|
||||||
|
expect(messages[1].getMessage()).toEqual(aliceMsg);
|
||||||
|
|
||||||
|
let bobMsg = "Hello I'm Bob";
|
||||||
|
await bob.sendChatMessage(tradeId, bobMsg);
|
||||||
|
await wait(TestConfig.maxTimePeerNoticeMs);
|
||||||
|
messages = await alice.getChatMessages(tradeId);
|
||||||
|
expect(messages.length).toEqual(3);
|
||||||
|
expect(messages[0].getIsSystemMessage()).toEqual(true);
|
||||||
|
expect(messages[1].getMessage()).toEqual(aliceMsg);
|
||||||
|
expect(messages[2].getMessage()).toEqual(bobMsg);
|
||||||
|
|
||||||
|
// verify notifications
|
||||||
|
let chatNotifications = getNotifications(aliceNotifications, NotificationMessage.NotificationType.CHAT_MESSAGE);
|
||||||
|
expect(chatNotifications.length).toBe(1);
|
||||||
|
expect(chatNotifications[0].getChatMessage()?.getMessage()).toEqual(bobMsg);
|
||||||
|
chatNotifications = getNotifications(bobNotifications, NotificationMessage.NotificationType.CHAT_MESSAGE);
|
||||||
|
expect(chatNotifications.length).toBe(1);
|
||||||
|
expect(chatNotifications[0].getChatMessage()?.getMessage()).toEqual(aliceMsg);
|
||||||
|
|
||||||
|
// additional msgs
|
||||||
|
let msgs = ["", " ", "<script>alert('test');</script>", "さようなら"];
|
||||||
|
for(let msg of msgs) {
|
||||||
|
await alice.sendChatMessage(tradeId, msg);
|
||||||
|
await wait(1000); // the async operation can result in out of order messages
|
||||||
|
}
|
||||||
|
await wait(TestConfig.maxTimePeerNoticeMs);
|
||||||
|
messages = await bob.getChatMessages(tradeId);
|
||||||
|
let offset = 3; // 3 existing messages
|
||||||
|
expect(messages.length).toEqual(offset + msgs.length);
|
||||||
|
expect(messages[0].getIsSystemMessage()).toEqual(true);
|
||||||
|
expect(messages[1].getMessage()).toEqual(aliceMsg);
|
||||||
|
expect(messages[2].getMessage()).toEqual(bobMsg);
|
||||||
|
for (var i = 0; i < msgs.length; i++) {
|
||||||
|
expect(messages[i+offset].getMessage()).toEqual(msgs[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
chatNotifications = getNotifications(bobNotifications, NotificationMessage.NotificationType.CHAT_MESSAGE);
|
||||||
|
offset = 1; // 1 existing notification
|
||||||
|
expect(chatNotifications.length).toBe(offset + msgs.length);
|
||||||
|
expect(chatNotifications[0].getChatMessage()?.getMessage()).toEqual(aliceMsg);
|
||||||
|
for (var i = 0; i < msgs.length; i++) {
|
||||||
|
expect(chatNotifications[i + offset].getChatMessage()?.getMessage()).toEqual(msgs[i]);
|
||||||
|
}
|
||||||
|
}
|
@ -2,8 +2,8 @@ import {HavenoUtils} from "./utils/HavenoUtils";
|
|||||||
import {TaskLooper} from "./utils/TaskLooper";
|
import {TaskLooper} from "./utils/TaskLooper";
|
||||||
import * as grpcWeb from 'grpc-web';
|
import * as grpcWeb from 'grpc-web';
|
||||||
import {GetVersionClient, AccountClient, MoneroConnectionsClient, DisputesClient, DisputeAgentsClient, NotificationsClient, WalletsClient, PriceClient, OffersClient, PaymentAccountsClient, TradesClient, ShutdownServerClient} from './protobuf/GrpcServiceClientPb';
|
import {GetVersionClient, AccountClient, MoneroConnectionsClient, DisputesClient, DisputeAgentsClient, NotificationsClient, WalletsClient, PriceClient, OffersClient, PaymentAccountsClient, TradesClient, ShutdownServerClient} from './protobuf/GrpcServiceClientPb';
|
||||||
import {GetVersionRequest, GetVersionReply, IsAppInitializedRequest, IsAppInitializedReply, RegisterDisputeAgentRequest, MarketPriceRequest, MarketPriceReply, MarketPricesRequest, MarketPricesReply, MarketPriceInfo, MarketDepthRequest, MarketDepthReply, MarketDepthInfo, GetBalancesRequest, GetBalancesReply, XmrBalanceInfo, GetMyOfferRequest, GetMyOfferReply, GetOffersRequest, GetOffersReply, OfferInfo, GetPaymentMethodsRequest, GetPaymentMethodsReply, GetPaymentAccountFormRequest, CreatePaymentAccountRequest, CreatePaymentAccountReply, GetPaymentAccountFormReply, GetPaymentAccountsRequest, GetPaymentAccountsReply, CreateCryptoCurrencyPaymentAccountRequest, CreateCryptoCurrencyPaymentAccountReply, CreateOfferRequest, CreateOfferReply, CancelOfferRequest, TakeOfferRequest, TakeOfferReply, TradeInfo, GetTradeRequest, GetTradeReply, GetTradesRequest, GetTradesReply, GetNewDepositSubaddressRequest, GetNewDepositSubaddressReply, ConfirmPaymentStartedRequest, ConfirmPaymentReceivedRequest, XmrTx, GetXmrTxsRequest, GetXmrTxsReply, XmrDestination, CreateXmrTxRequest, CreateXmrTxReply, RelayXmrTxRequest, RelayXmrTxReply, CreateAccountRequest, AccountExistsRequest, AccountExistsReply, DeleteAccountRequest, OpenAccountRequest, IsAccountOpenRequest, IsAccountOpenReply, CloseAccountRequest, ChangePasswordRequest, BackupAccountRequest, BackupAccountReply, RestoreAccountRequest, StopRequest, NotificationMessage, RegisterNotificationListenerRequest, SendNotificationRequest, UrlConnection, AddConnectionRequest, RemoveConnectionRequest, GetConnectionRequest, GetConnectionsRequest, SetConnectionRequest, CheckConnectionRequest, CheckConnectionsReply, CheckConnectionsRequest, StartCheckingConnectionsRequest, StopCheckingConnectionsRequest, GetBestAvailableConnectionRequest, SetAutoSwitchRequest, CheckConnectionReply, GetConnectionsReply, GetConnectionReply, GetBestAvailableConnectionReply, GetDisputeRequest, GetDisputeReply, GetDisputesRequest, GetDisputesReply, OpenDisputeRequest, ResolveDisputeRequest, SendDisputeChatMessageRequest} from './protobuf/grpc_pb';
|
import {GetVersionRequest, GetVersionReply, IsAppInitializedRequest, IsAppInitializedReply, RegisterDisputeAgentRequest, MarketPriceRequest, MarketPriceReply, MarketPricesRequest, MarketPricesReply, MarketPriceInfo, MarketDepthRequest, MarketDepthReply, MarketDepthInfo, GetBalancesRequest, GetBalancesReply, XmrBalanceInfo, GetMyOfferRequest, GetMyOfferReply, GetOffersRequest, GetOffersReply, OfferInfo, GetPaymentMethodsRequest, GetPaymentMethodsReply, GetPaymentAccountFormRequest, CreatePaymentAccountRequest, CreatePaymentAccountReply, GetPaymentAccountFormReply, GetPaymentAccountsRequest, GetPaymentAccountsReply, CreateCryptoCurrencyPaymentAccountRequest, CreateCryptoCurrencyPaymentAccountReply, CreateOfferRequest, CreateOfferReply, CancelOfferRequest, TakeOfferRequest, TakeOfferReply, TradeInfo, GetTradeRequest, GetTradeReply, GetTradesRequest, GetTradesReply, GetNewDepositSubaddressRequest, GetNewDepositSubaddressReply, ConfirmPaymentStartedRequest, ConfirmPaymentReceivedRequest, XmrTx, GetXmrTxsRequest, GetXmrTxsReply, XmrDestination, CreateXmrTxRequest, CreateXmrTxReply, RelayXmrTxRequest, RelayXmrTxReply, CreateAccountRequest, AccountExistsRequest, AccountExistsReply, DeleteAccountRequest, OpenAccountRequest, IsAccountOpenRequest, IsAccountOpenReply, CloseAccountRequest, ChangePasswordRequest, BackupAccountRequest, BackupAccountReply, RestoreAccountRequest, StopRequest, NotificationMessage, RegisterNotificationListenerRequest, SendNotificationRequest, UrlConnection, AddConnectionRequest, RemoveConnectionRequest, GetConnectionRequest, GetConnectionsRequest, SetConnectionRequest, CheckConnectionRequest, CheckConnectionsReply, CheckConnectionsRequest, StartCheckingConnectionsRequest, StopCheckingConnectionsRequest, GetBestAvailableConnectionRequest, SetAutoSwitchRequest, CheckConnectionReply, GetConnectionsReply, GetConnectionReply, GetBestAvailableConnectionReply, GetDisputeRequest, GetDisputeReply, GetDisputesRequest, GetDisputesReply, OpenDisputeRequest, ResolveDisputeRequest, SendDisputeChatMessageRequest, SendChatMessageRequest, GetChatMessagesRequest, GetChatMessagesReply} from './protobuf/grpc_pb';
|
||||||
import {PaymentMethod, PaymentAccount, AvailabilityResult, Attachment, DisputeResult, Dispute} from './protobuf/pb_pb';
|
import {PaymentMethod, PaymentAccount, AvailabilityResult, Attachment, DisputeResult, Dispute, ChatMessage} from './protobuf/pb_pb';
|
||||||
|
|
||||||
const console = require('console');
|
const console = require('console');
|
||||||
|
|
||||||
@ -1027,6 +1027,41 @@ class HavenoDaemon {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get all chat messages for a trade.
|
||||||
|
*
|
||||||
|
* @param {string} tradeId - the id of the trade
|
||||||
|
*/
|
||||||
|
async getChatMessages(tradeId: string): Promise<ChatMessage[]> {
|
||||||
|
let that = this;
|
||||||
|
return new Promise(function(resolve, reject) {
|
||||||
|
let request = new GetChatMessagesRequest().setTradeId(tradeId);
|
||||||
|
that._tradesClient.getChatMessages(request, {password: that._password}, function(err: grpcWeb.RpcError, response: GetChatMessagesReply) {
|
||||||
|
if (err) reject(err);
|
||||||
|
else resolve(response.getMessageList());
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Send a trade chat message.
|
||||||
|
*
|
||||||
|
* @param {string} tradeId - the id of the trade
|
||||||
|
* @param {string} message - the message
|
||||||
|
*/
|
||||||
|
async sendChatMessage(tradeId: string, message: string): Promise<void> {
|
||||||
|
let that = this;
|
||||||
|
return new Promise(function(resolve, reject) {
|
||||||
|
let request = new SendChatMessageRequest()
|
||||||
|
.setTradeId(tradeId)
|
||||||
|
.setMessage(message);
|
||||||
|
that._tradesClient.sendChatMessage(request, {password: that._password}, function(err: grpcWeb.RpcError) {
|
||||||
|
if (err) reject(err);
|
||||||
|
else resolve();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get a dispute by trade id.
|
* Get a dispute by trade id.
|
||||||
*
|
*
|
||||||
|
Loading…
x
Reference in New Issue
Block a user