send data file to another computer with RTCPeerConnection? - javascript

how can I change the code so that the computer1 code connects to the code of computer 2(computer1 and computer2 are not the same computers but on the same network).
It works locally but not when it's two different computers
computer 1 and computer2 code that is used for the connection is defined below
this is the code that does the networking on computer1
async function createConnection() {
abortButton.disabled = false;
sendFileButton.disabled = true;
localConnection = new RTCPeerConnection();//this is the line I think I need to change
console.log('Created local peer connection object localConnection');
sendChannel = localConnection.createDataChannel('sendDataChannel');
sendChannel.binaryType = 'arraybuffer';
console.log('Created send data channel');
sendChannel.addEventListener('open', onSendChannelStateChange);
sendChannel.addEventListener('close', onSendChannelStateChange);
sendChannel.addEventListener('error', onError);
localConnection.addEventListener('icecandidate', async event => {
console.log('Local ICE candidate: ', event.candidate);
await localConnection.addIceCandidate(event.candidate);
});
this is the part of the program that have the role to receive the request and the file data on the computer2
async function server(){
remoteConnection = new RTCPeerConnection();
alert("start");
console.log('Created remote peer connection object remoteConnection');
remoteConnection.addEventListener('icecandidate', async event => {
console.log('Remote ICE candidate: ', event.candidate);
await localConnection.addIceCandidate(event.candidate);
});
remoteConnection.addEventListener('datachannel', receiveChannelCallback);
}
the code that I modified(main.js)
/* eslint no-unused-expressions: 0 */
/*
* Copyright (c) 2015 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree.
*/
'use strict';
let localConnection;
let remoteConnection;
let sendChannel;
let receiveChannel;
let fileReader;
const bitrateDiv = document.querySelector('div#bitrate');
const fileInput = document.querySelector('input#fileInput');
const abortButton = document.querySelector('button#abortButton');
const downloadAnchor = document.querySelector('a#download');
const sendProgress = document.querySelector('progress#sendProgress');
const receiveProgress = document.querySelector('progress#receiveProgress');
const statusMessage = document.querySelector('span#status');
const sendFileButton = document.querySelector('button#sendFile');
let receiveBuffer = [];
let receivedSize = 0;
let bytesPrev = 0;
let timestampPrev = 0;
let timestampStart;
let statsInterval = null;
let bitrateMax = 0;
server();
sendFileButton.addEventListener('click', () => createConnection());
fileInput.addEventListener('change', handleFileInputChange, false);
abortButton.addEventListener('click', () => {
if (fileReader && fileReader.readyState === 1) {
console.log('Abort read!');
fileReader.abort();
}
});
async function handleFileInputChange() {
const file = fileInput.files[0];
if (!file) {
console.log('No file chosen');
} else {
sendFileButton.disabled = false;
}
}
async function server(){
//const servers = {
//iceServers: [
// {
// urls: ['stun:stun1.l.google.com:19302', //'stun:stun2.l.google.com:19302'],
// },
//],
//iceCandidatePoolSize: 10,
//};
remoteConnection = new RTCPeerConnection();
alert("start");
console.log('Created remote peer connection object remoteConnection');
remoteConnection.addEventListener('icecandidate', async event => {
console.log('Remote ICE candidate: ', event.candidate);
await localConnection.addIceCandidate(event.candidate);
});
remoteConnection.addEventListener('datachannel', receiveChannelCallback);
}
async function createConnection() {
abortButton.disabled = false;
sendFileButton.disabled = true;
//const servers = {
//iceServers: [
// {
// urls: ['stun:stun1.l.google.com:19302', //'stun:stun2.l.google.com:19302'],
// },
//],
//iceCandidatePoolSize: 10,
//};
localConnection = new RTCPeerConnection();
console.log('Created local peer connection object localConnection');
sendChannel = localConnection.createDataChannel('sendDataChannel');
sendChannel.binaryType = 'arraybuffer';
console.log('Created send data channel');
sendChannel.addEventListener('open', onSendChannelStateChange);
sendChannel.addEventListener('close', onSendChannelStateChange);
sendChannel.addEventListener('error', onError);
localConnection.addEventListener('icecandidate', async event => {
console.log('Local ICE candidate: ', event.candidate);
await localConnection.addIceCandidate(event.candidate);
});
try {
const offer = await localConnection.createOffer();
await gotLocalDescription(offer);
} catch (e) {
console.log('Failed to create session description: ', e);
}
fileInput.disabled = true;
}
function sendData() {
const file = fileInput.files[0];
console.log(`File is ${[file.name, file.size, file.type, file.lastModified].join(' ')}`);
// Handle 0 size files.
statusMessage.textContent = '';
downloadAnchor.textContent = '';
if (file.size === 0) {
bitrateDiv.innerHTML = '';
statusMessage.textContent = 'File is empty, please select a non-empty file';
closeDataChannels();
return;
}
sendProgress.max = file.size;
receiveProgress.max = file.size;
const chunkSize = 16384;
fileReader = new FileReader();
let offset = 0;
fileReader.addEventListener('error', error => console.error('Error reading file:', error));
fileReader.addEventListener('abort', event => console.log('File reading aborted:', event));
fileReader.addEventListener('load', e => {
console.log('FileRead.onload ', e);
sendChannel.send(e.target.result);
offset += e.target.result.byteLength;
sendProgress.value = offset;
if (offset < file.size) {
readSlice(offset);
}
});
const readSlice = o => {
console.log('readSlice ', o);
const slice = file.slice(offset, o + chunkSize);
fileReader.readAsArrayBuffer(slice);
};
readSlice(0);
}
function closeDataChannels() {
console.log('Closing data channels');
sendChannel.close();
console.log(`Closed data channel with label: ${sendChannel.label}`);
sendChannel = null;
if (receiveChannel) {
receiveChannel.close();
console.log(`Closed data channel with label: ${receiveChannel.label}`);
receiveChannel = null;
}
localConnection.close();
remoteConnection.close();
localConnection = null;
remoteConnection = null;
console.log('Closed peer connections');
// re-enable the file select
fileInput.disabled = false;
abortButton.disabled = true;
sendFileButton.disabled = false;
}
async function gotLocalDescription(desc) {
await localConnection.setLocalDescription(desc);
console.log(`Offer from localConnection\n ${desc.sdp}`);
await remoteConnection.setRemoteDescription(desc);
try {
const answer = await remoteConnection.createAnswer();
await gotRemoteDescription(answer);
} catch (e) {
console.log('Failed to create session description: ', e);
}
}
async function gotRemoteDescription(desc) {
await remoteConnection.setLocalDescription(desc);
console.log(`Answer from remoteConnection\n ${desc.sdp}`);
await localConnection.setRemoteDescription(desc);
}
function receiveChannelCallback(event) {
console.log('Receive Channel Callback');
receiveChannel = event.channel;
receiveChannel.binaryType = 'arraybuffer';
receiveChannel.onmessage = onReceiveMessageCallback;
receiveChannel.onopen = onReceiveChannelStateChange;
receiveChannel.onclose = onReceiveChannelStateChange;
receivedSize = 0;
bitrateMax = 0;
downloadAnchor.textContent = '';
downloadAnchor.removeAttribute('download');
if (downloadAnchor.href) {
URL.revokeObjectURL(downloadAnchor.href);
downloadAnchor.removeAttribute('href');
}
}
function onReceiveMessageCallback(event) {
console.log(`Received Message ${event.data.byteLength}`);
receiveBuffer.push(event.data);
receivedSize += event.data.byteLength;
receiveProgress.value = receivedSize;
// we are assuming that our signaling protocol told
// about the expected file size (and name, hash, etc).
const file = fileInput.files[0];
if (receivedSize === file.size) {
const received = new Blob(receiveBuffer);
receiveBuffer = [];
downloadAnchor.href = URL.createObjectURL(received);
downloadAnchor.download = file.name;
downloadAnchor.textContent =
`Click to download '${file.name}' (${file.size} bytes)`;
downloadAnchor.style.display = 'block';
const bitrate = Math.round(receivedSize * 8 /
((new Date()).getTime() - timestampStart));
bitrateDiv.innerHTML =
`<strong>Average Bitrate:</strong> ${bitrate} kbits/sec (max: ${bitrateMax} kbits/sec)`;
if (statsInterval) {
clearInterval(statsInterval);
statsInterval = null;
}
closeDataChannels();
}
}
function onSendChannelStateChange() {
if (sendChannel) {
const {readyState} = sendChannel;
console.log(`Send channel state is: ${readyState}`);
if (readyState === 'open') {
sendData();
}
}
}
function onError(error) {
if (sendChannel) {
console.error('Error in sendChannel:', error);
return;
}
console.log('Error in sendChannel which is already closed:', error);
}
async function onReceiveChannelStateChange() {
if (receiveChannel) {
const readyState = receiveChannel.readyState;
console.log(`Receive channel state is: ${readyState}`);
if (readyState === 'open') {
timestampStart = (new Date()).getTime();
timestampPrev = timestampStart;
statsInterval = setInterval(displayStats, 500);
await displayStats();
}
}
}
// display bitrate statistics.
async function displayStats() {
if (remoteConnection && remoteConnection.iceConnectionState === 'connected') {
const stats = await remoteConnection.getStats();
let activeCandidatePair;
stats.forEach(report => {
if (report.type === 'transport') {
activeCandidatePair = stats.get(report.selectedCandidatePairId);
}
});
if (activeCandidatePair) {
if (timestampPrev === activeCandidatePair.timestamp) {
return;
}
// calculate current bitrate
const bytesNow = activeCandidatePair.bytesReceived;
const bitrate = Math.round((bytesNow - bytesPrev) * 8 /
(activeCandidatePair.timestamp - timestampPrev));
bitrateDiv.innerHTML = `<strong>Current Bitrate:</strong> ${bitrate} kbits/sec`;
timestampPrev = activeCandidatePair.timestamp;
bytesPrev = bytesNow;
if (bitrate > bitrateMax) {
bitrateMax = bitrate;
}
}
}
}
Thanks for helping

You can read about peer connections where every peer connection is handled by the RTCPeerConnection object and it defines how the peer connection is set up and how it should include the information about the ICE servers to use.
You can define the ICE servers as following:
localConnection = new RTCPeerConnection({iceServers: [{ url: "stun:"+ ip +":8003" }]})
or
localConnection = new RTCPeerConnection({iceServers: [{ url: + ip + ':port' }]})
or
var servers = {
iceTransportPolicy: 'relay',
iceServers: [{
urls: "turn:[" + ip + "]:3478",
username: "username",
credential: "password"
}
]};
var localConnection = new RTCPeerConnection(servers);
Moreover, You can find the full code here or
here under the folder name filetransfer .

Related

IndexedDB fully backup and restore of databases (without Dexie.js)

I want to backup IndexedDB into json file, and restore it on another machine / browser.
the goal is to fully backup and import website session (localStorage, cookies etc...)
I think that dumpIndexedDb() function works correctly,
the problem occur when I try to get this data and restore it back using restoreIndexedDbDump(data). there's no errors.
but only few databases restored.
I'm pretty sure I was missed something with indexedDB api in the restore operation.
thanks in advance.
function dumpDB(dbName) {
return new Promise((resolve, reject) => {
var request = indexedDB.open(dbName)
request.onerror = e => reject(e)
request.onsuccess = (e) => {
var data = {} // { dbVersion: 1, oName: {keyPath: 'key', data: [{},{}]} }
var db = e.target.result
var dbVersion = db.version
data['dbVersion'] = dbVersion
data['objectStores'] = {}
var oStores = db.objectStoreNames
for (let osName of oStores) {
var transaction = db.transaction(osName, "readonly")
var oStore = transaction.objectStore(osName)
var keyPath = oStore.keyPath
data['objectStores'][osName] = {}
data['objectStores'][osName]['keyPath'] = keyPath
var request = oStore.getAll()
request.onerror = e => reject(e)
request.onsuccess = (e) => {
data['objectStores'][osName]['data'] = e.target.result
}
}
db.close()
resolve(data)
}
})
}
async function dumpIndexedDb() {
var data = {}
var dbs = await indexedDB.databases() // not working in firefox, tested in chrome.
for (let db of dbs) {
var dbData = await dumpDB(db.name)
data[db.name] = dbData
}
return data // {dbName: { dbVersion: 1, oName: {keyPath: 'key', data: [{},{}]} } }
}
function restoreObjectStore(dbName, version, oName, keyPath, data) {
return new Promise((resolve, reject) => {
request = window.indexedDB.open(dbName, version);
request.onerror = e => reject(e)
request.onupgradeneeded = function (e) {
try {
var db = e.target.result
if (keyPath) var objectStore = db.createObjectStore(oName, { keyPath: keyPath, autoIncrement: false })
else var objectStore = db.createObjectStore(oName, { autoIncrement: false })
for (let row of data) {
console.log(`adding row of ${oName}`)
}
objectStore.transaction.commit()
db.close()
resolve("ok")
} catch(e) {
reject(e)
}
}
})
}
async function restoreIndexedDbDump(data) {
for (let dbName in data) {
console.log(`deleting db ${dbName}`)
indexedDB.deleteDatabase(dbName)
for (let oStoreName in data[dbName]['objectStores']) {
let odata = data[dbName]['objectStores'][oStoreName]['data']
let dbVersion = data[dbName]['dbVersion']
if ( data[dbName]['objectStores'][oStoreName]['keyPath'] ) {
var keyPath = data[dbName]['objectStores'][oStoreName]['keyPath']
await restoreObjectStore(dbName, dbVersion, oStoreName, keyPath, odata)
}
else {
await restoreObjectStore(dbName, dbVersion, oStoreName, null, odata)
}
}
}
}
async function testBackupandRestore() {
var data = await dumpIndexedDb()
await restoreIndexedDbDump(data)
}

problem with bi-directional video conferencing webrtc

Thanks in advance.
I am following the guide to implement webrtc from the official page:
https://webrtc.org/
And I am having trouble for two-way communication. On one pc I have a video camera and on the other only a microphone.
I manage to receive the camcorder, but I cannot receive the .ontrack event on the pc that sends the camcorder and it has to receive only the audio, when I am adding the track on the computer that sends the audio but not launch event .ontrack on remote machine.
The connection is made correctly, here paste the connection and the code
MY CODE one one localhost/video.php antother localhsot/video.php?cliente=1
<?php
/**
* Created by PhpStorm.
* User: Jesús
* Date: 16/03/2020
* Time: 13:16
*/
?>
<video id="localVideo" autoplay <?= !isset($_GET['cliente']) ? 'muted' : '' ?> playsinline controls="false" style="width: 600px; height: 320px;"></video>
<?php
if(!isset($_GET['cliente'])) {
?>
<button onclick="makeCallAdmin()">enviar llamada</button>
<?php
}
?>
<script src="../app/js/lib/socket.io.js"></script>
<script>
let cliente = <?= isset($_GET['cliente']) ? 'true' : 'false' ?>;
let tipo = cliente ? 'client' : 'admin';
var ipSocket = 'SCOCKETADDRESS';
// var ipSocket = 'https://192.168.125.175:3001';
var idgrupo = '5ed44424c2df0470d689.4f6370fbe1ac319e5dc1d7417822d28a';
var socket = io(ipSocket, {
query: "grupo=" + idgrupo + "&tipo=" + tipo
});
const iceConfiguration = {
iceServers: [
{
urls: 'stun:stun.l.google.com:19302?transport=udp'
},
{
urls: 'turns:turnserver',
username: 'prueba',
credential: '123456'
}
],
}
const offerOptions = {
offerToReceiveAudio: 1,
offerToReceiveVideo: 1
};
// let peerConnection, remoteStream, videoElement;
let peerConnection;
let fuerzaConectar;
async function getConnectedDevices(type) {
const devices = await navigator.mediaDevices.enumerateDevices();
return await devices.filter(device => device.kind === type)
}
// Open camera with at least minWidth and minHeight capabilities
async function openCamera(cameraId, audioid) {
let constraints;
if(!cameraId) {
constraints = {
'audio': {'echoCancellation': true}
}
}else{
constraints = {
'audio': {'echoCancellation': true},
'video': {
'deviceId': cameraId
}
}
}
// constraints = {'video': true, 'audio': true};
return await navigator.mediaDevices.getUserMedia(constraints);
}
async function playVideoFromCamera(peerConnection, type, fuerza) {
if(type == null)
type = 'videoinput';
if(fuerza == null)
fuerza = false;
try {
const cameras = await getConnectedDevices(type);
if (cameras && cameras.length > 0) {
let stream;
if(fuerza) //si solo ha encontrado el audio enviamos solo audio
stream = await openCamera(false, cameras[0].deviceId);
else //si ha encontrado camara enviamos camara y audio
stream = await openCamera(cameras[0].deviceId, false);
stream.getTracks().forEach(track => {
peerConnection.addTrack(track, stream);
});
}else{
if(!fuerza)
await playVideoFromCamera(peerConnection, 'audioinput', true);
else
console.log('no hay input');
}
} catch(error) {
console.error('Error opening video camera.', error);
}
}
async function makeCallAdmin() {
fuerzaConectar = (fuerzaConectar == null | !fuerzaConectar) ? true : false;
if(typeof peerConnection == 'object') {
peerConnection.close();
peerConnection = null;
const videoElement = document.querySelector('video#localVideo');
videoElement.srcObject = null;
if(cliente)
socket.off('videoconferenciaRecibeCliente');
else
socket.off('videoconferenciaRecibeAdmin');
}
peerConnection = new RTCPeerConnection(iceConfiguration);
const remoteStream = new MediaStream();
// Listen for local ICE candidates on the local RTCPeerConnection
// peerConnection.removeEventListener('icecandidate', iceCandidate);
// peerConnection.addEventListener('icecandidate', iceCandidate);
peerConnection.onicecandidate = e => iceCandidate(e);
// Listen for connectionstatechange on the local RTCPeerConnection
// peerConnection.removeEventListener('iceconnectionstatechange', iceconnectionstatechange);
peerConnection.oniceconnectionstatechange = e => iceconnectionstatechange(e, peerConnection);
// peerConnection.removeEventListener('track', track);
// peerConnection.addEventListener('track', trackEv);
peerConnection.ontrack = e => trackEv(e, remoteStream);
socket.on('videoconferenciaRecibeAdmin', data => videoconferenciaRecibeAdmin(data, peerConnection));
const offer = await peerConnection.createOffer(offerOptions);
await peerConnection.setLocalDescription(offer);
socket.emit('videoconferenciaAdmin', {'tipo':'remoteDescription','offer': offer});
}
async function makeCallCliente()
{
fuerzaConectar = (fuerzaConectar == null | !fuerzaConectar) ? true : false;
if(typeof peerConnection == 'object') {
peerConnection.close();
peerConnection = null;
const videoElement = document.querySelector('video#localVideo');
videoElement.srcObject = null;
if(cliente)
socket.off('videoconferenciaRecibeCliente');
else
socket.off('videoconferenciaRecibeAdmin');
}
peerConnection = await new RTCPeerConnection(iceConfiguration);
const remoteStream = await new MediaStream();
// Listen for local ICE candidates on the local RTCPeerConnection
// peerConnection.removeEventListener('icecandidate', iceCandidate);
// peerConnection.addEventListener('icecandidate', iceCandidate);
peerConnection.onicecandidate = e => iceCandidate(e);
// Listen for connectionstatechange on the local RTCPeerConnection
// peerConnection.removeEventListener('iceconnectionstatechange', iceconnectionstatechange);
peerConnection.oniceconnectionstatechange = e => iceconnectionstatechange(e, peerConnection);
// peerConnection.removeEventListener('track', track);
// peerConnection.addEventListener('track', trackEv);
peerConnection.ontrack = e => trackEv(e, remoteStream);
socket.on('videoconferenciaRecibeCliente', data => videoconferenciaRecibeCliente(data, peerConnection, ));
}
async function videoconferenciaRecibeCliente(data, peerConnection)
{
switch(data.tipo) {
case 'remoteDescription':
if (data.offer) {
console.log(data.offer);
await peerConnection.setRemoteDescription(new RTCSessionDescription(data.offer));
const answer = await peerConnection.createAnswer(offerOptions);
await peerConnection.setLocalDescription(answer);
await socket.emit('videoconferenciaCliente', {'tipo':'remoteDescription','answer': answer});
console.log('recibida conexion cliente');
console.log(peerConnection);
}
break;
case 'icecandidate':
if (data.icecandidate) {
try {
await peerConnection.addIceCandidate(data.icecandidate);
console.log('creado ice candidate cliente');
console.log(data.icecandidate);
} catch (e) {
console.error('Error adding received ice candidate', e);
}
}
break;
}
}
async function videoconferenciaRecibeAdmin(data, peerConnection)
{
switch(data.tipo) {
case 'remoteDescription':
if (data.answer) {
console.log(data.answer);
const remoteDesc = new RTCSessionDescription(data.answer);
await peerConnection.setRemoteDescription(remoteDesc);
console.log('recibida conexion admin');
console.log(peerConnection);
}
break;
case 'icecandidate':
if (data.icecandidate) {
try {
await peerConnection.addIceCandidate(data.icecandidate);
console.log('creado ice candidate admin');
console.log(data.icecandidate);
} catch (e) {
console.error('Error adding received ice candidate', e);
}
}
break;
}
}
async function iceCandidate(event)
{
let el_evento = cliente ? 'videoconferenciaCliente' : 'videoconferenciaAdmin';
if (event.candidate) {
socket.emit(el_evento, {'tipo':'icecandidate','icecandidate': event.candidate});
}
}
async function iceconnectionstatechange(event, peerConnection)
{
console.log(peerConnection.iceConnectionState);
switch(peerConnection.iceConnectionState) {
case 'connected':
console.log('CONECTADO');
await enviarLLamada(peerConnection);
switch(true) {
case fuerzaConectar && cliente:
// makeCallCliente();
break;
case fuerzaConectar && !cliente:
makeCallAdmin();
break;
}
break;
case 'disconnected':
console.log('DESconectado');
await peerConnection.close();
peerConnection = null;
const videoElement = document.querySelector('video#localVideo');
videoElement.srcObject = null;
if(cliente)
await socket.off('videoconferenciaRecibeCliente');
else
await socket.off('videoconferenciaRecibeAdmin');
break;
}
}
async function trackEv(event, remoteStream)
{
const videoElement = document.querySelector('video#localVideo');
if(videoElement.srcObject == null)
videoElement.srcObject = remoteStream;
console.log('entra a TRACK');
await remoteStream.addTrack(event.track, remoteStream);
// videoElement.play();
}
async function enviarLLamada(peerConnection)
{
await playVideoFromCamera(peerConnection);
}
document.addEventListener("DOMContentLoaded", function(event) {
if(cliente)
makeCallCliente();
// else
// makeCallAdmin();
});
</script>

Websocket with kraken closes after sending subscription for open position

I am trying to subscribe to the kraken websocket API for the OpenPositions. I have sent a challenge request and receive the challenge , i also have signed it correctly with my secret key but it seems like once i sent the openpositions subsctiption request, the web socket closes directly with a code of 1006 and reasons ''.
I am writing in Nodejs using the native library websocket and event emiiter to emit data of "kraken-update"
this is the main file that i run:
const con = new Connection(key = keys.api_key, secret=keys.secret);
con.on('kraken-update', (data) => {
console.log(new Date, "DATA", data);
return;
});
const go = async(key, secret) => {
console.log(new Date, 'connecting...');
await con.connect();
console.log(new Date, 'connected');
await con.sendchallenge()
}
and here is the Connection class
const WebSocket = require('ws');
const crypto = require('crypto');
const EventEmitter = require('events');
class Connection extends EventEmitter {
constructor( key, secret, challenge = '') {
super();
this.url = 'wss://futures.kraken.com/ws/v1';
this.connected = false;
this.challenge = challenge;
this.lastMessageAt = 0;
this.key=key;
this.secret=secret;
}
disconnect() {
this.ws.disconnect();
}
connect() {
if(this.connected) {
console.log("ALREADY CONNECTED")
return;
}
let readyHook;
this.onOpen = new Promise(r => readyHook = r);
this.ws = new WebSocket(this.url);
this.ws.onopen = () => {
this.connected = true;
readyHook();
}
this.ws.onerror = (e) => {
console.log(new Date, '[KRAKEN] error', e);
}
this.ws.onclose = (e) => {
console.log(new Date, '[KRAKEN] close', e);
}
this.ws.onmessage = (e) => {
//console.log("MESSAGE ",e.data)
setImmediate(()=>this.handleMessage(e))
}
// initial book data coming in on the same tick as the subscription data
// we defer this so the subscription promise resloves before we send
// initial OB data.
return this.onOpen;
}
handleMessage(e){
this.lastMessageAt = new Date;
console.log(e)
const payload = JSON.parse(e.data);
if(payload.event === 'subscribed') {
this.emit('kraken-update', payload)
console.log(new Date, "SUBSCRIBED ",payload)
return;
}
if (payload.event === 'challenge'){
this.challenge = payload.message
this.emit('kraken-update', payload.message);
this.subscribeOpenPositions();
return;
}
if (payload.feed === "open_positions"){
this.emit('kraken-update', payload.message);
return;
}
else{
console.log(new Date, "UNDETECTED ",payload)
return;
}
}
sendchallenge(){
try{
let onReady = new Promise(e => e);
const data = JSON.stringify({'event': 'challenge','api_key':this.key})
this.ws.send(data);
return onReady;
}
catch(e){
console.log(new Date, 'ERROR SENDING CHALLENGE')
throw(e)
}
}
subscribeOpenPositions(){
//how to sign challenge:
//https://support.kraken.com/hc/en-us/articles/360022635652-Sign-Challenge-Web-Socket-API-
console.log(new Date, `SUBSCRIBING OPENPOSITION WITH ${this.challenge}....`);
try{
const secret_buffer = new Buffer.from(this.secret, 'base64');
const hash = new crypto.createHash('sha256');
const hmac = new crypto.createHmac('sha512', secret_buffer);
const hash_digest = hash.update(this.challenge).digest('binary');
const hmac_digest = hmac.update(hash_digest, 'binary').digest('base64');
this.ws.send(JSON.stringify({"event":"ping"}))
this.ws.send(JSON.stringify(
{"event":"subscribe",
"feed":"open_positions",
"api_key":this.key,
"original_challenge":this.challenge,
"signed_challenge":hmac_digest}
));
console.log("SENT");
}
catch(e){
console.log(new Date,"ERROR SENDING SUBSCRIPTION REQUEST")
throw(e)
}
}
}
module.exports = Connection;
summary of what happened:
connnect to kraken future server => request challenge => handle challenge then request openorder subscription while handling challenge => websocket closes

IndexedDB takes time to initialize outer scope variable db which is needed in another function

I am opening a database using indexedDB using javascript for keeping a diary entry. I am doing three things with the database: display all entry, add entry, and remove entry.
It fails when it tries to create a transaction because 'db' is 'undefined.' I was expecting db to be defined by the time the code tries to create a transaction.
Error is caused at the line with code:
const getObjectStore = (storeName, mode) => {
console.log('db: ', db);
const tx = db.transaction(storeName, mode); // error is thrown because db is undefined
return tx.objectStore(storeName);
};
I tried to put console.log at different places to see what is wrong. I found that db takes time before it gets defined by an onsuccess response or onupgradeneeded response. I don't see any other way to define db before it is used. Can you show me how I can assure myself for the assignment of db before it is used?
Outputs:
> adding something in the diary
> db from getObjectStore: undefined
> Uncaught TypeError: Cannot read property 'transaction' of undefined
at getObjectStore (script.js:35)
at Object.setAnEntry [as add] (script.js:62)
at script.js:81
at script.js:215
getObjectStore # script.js:35
setAnEntry # script.js:62
(anonymous) # script.js:81
(anonymous) # script.js:215
> there is indexeddb!
> db: IDBDatabase {name: "medDiary", version: 1, objectStoreNames: DOMStringList, onabort: null, onclose: null, …}
All the code i am working with:
// DATABASE FOR THE DIARY
const Dairy = (() => {
if (window.indexedDB) {
let db;
const DB_NAME = 'Dairy';
const DB_VERSION = 1;
const DB_STORE_NAME = 'diaries';
const request = window.indexedDB.open(DB_NAME, DB_VERSION);
request.onerror = () => {
console.log('Error requesting to open database permission denied.');
};
request.onsuccess = (event) => {
console.log('there is indexeddb!');
db = event.target.result;
console.log('db: ', db);
db.onerror = (evt) => {
console.error(`Database error: ${evt.target.errorCode}`);
};
};
request.onupgradeneeded = (event) => {
db = request.result;
const store = event.currentTarget.result.createObjectStore(DB_STORE_NAME, { keyPath: 'date' });
store.createIndex('subject', 'subject', { unique: false });
store.createIndex('date', 'date', { unique: true });
store.createIndex('description', 'description', { unique: false });
};
const getObjectStore = (storeName, mode) => {
console.log('db from getObjectStore: ', db);
const tx = db.transaction(storeName, mode);
return tx.objectStore(storeName);
};
const getAllEntries = () => new Promise((resolve) => {
const result = [];
const store = getObjectStore(DB_STORE_NAME, 'readonly');
const req = store.openCursor();
req.onsuccess = (evt) => {
const cursor = evt.target.result;
if (cursor) {
const retrive = store.get(cursor.key);
retrive.onsuccess = function (evt) {
const value = evt.target.result;
result.append(value);
};
cursor.continue();
} else {
console.log('No more entries');
resolve(result);
}
};
});
const setAnEntry = (value) => {
const store = getObjectStore(DB_STORE_NAME, 'readwrite');
store.put(value);
};
const removeAnEntry = (value) => {
const store = getObjectStore(DB_STORE_NAME, 'readwrite');
store.remove(value);
};
return {
all: getAllEntries,
add: setAnEntry,
remove: removeAnEntry,
};
}
alert("Your browser doesn't support a stable version of IndexedDB. Dairy related features will not be available.");
return {};
})();
console.log('adding something in the diary');
console.log('... ', Dairy.add({ subject: 'hello', description: 'bluh bluh', date: Date() }));
console.log('show all: ', Dairy.all());
You can use a promise to open the DB:
let promise = new Promise(function(resolve, reject)
{
//check for support
if (!('indexedDB' in window)) {
//console.log('This browser doesn\'t support IndexedDB');
reject("indexedDB not supported");
}
var request = indexedDB.open(dbName, dbVersion);
request.onerror = function (event) {
reject("Error opening DB");
};
request.onsuccess = function (event) {
console.log("opened!");
db = request.result;
resolve(true);
};
});
And then you can use:
promise
.then(
result => {
your stuff here sine the DB is now open!!
},
error => console.log(error)
)
The parameter passed to resolve will be available as 'result'.
To use in your module format:
Add init function:
async function init()
{
let promise = new Promise(function(resolve, reject)
{
//check for support
if (!('indexedDB' in window)) {
//console.log('This browser doesn\'t support IndexedDB');
reject("indexedDB not supported");
}
var request = indexedDB.open(dbName, dbVersion);
request.onerror = function (event) {
reject("Error opening DB");
};
request.onsuccess = function (event) {
console.log("opened!");
db = request.result;
resolve(true);
};
});
let result = await promise;
}
Your module rewritten:
const Dairy = (() => {
if (window.indexedDB)
{
let db;
const DB_NAME = 'Dairy';
const DB_VERSION = 1;
const DB_STORE_NAME = 'diaries';
async function init()
{
let promise = new Promise(function(resolve, reject)
{
const request = window.indexedDB.open(DB_NAME, DB_VERSION);
request.onerror = () => {
reject('Error requesting to open database permission denied.');
};
request.onsuccess = (event) => {
console.log('there is indexeddb!');
db = event.target.result;
console.log('db: ', db);
db.onerror = (evt) => {
reject("Database error: ${evt.target.errorCode}");
};
resolve(true);
};
request.onupgradeneeded = (event) => {
db = request.result;
const store = event.currentTarget.result.createObjectStore(DB_STORE_NAME, { keyPath: 'date' });
store.createIndex('subject', 'subject', { unique: false });
store.createIndex('date', 'date', { unique: true });
store.createIndex('description', 'description', { unique: false });
};
});
return promise;
}
const getObjectStore = (storeName, mode) => {
console.log('db from getObjectStore: ', db);
const tx = db.transaction(storeName, mode);
return tx.objectStore(storeName);
};
const getAllEntries = () => new Promise((resolve) => {
const result = [];
const store = getObjectStore(DB_STORE_NAME, 'readonly');
const req = store.openCursor();
req.onsuccess = (evt) => {
const cursor = evt.target.result;
if (cursor) {
const retrive = store.get(cursor.key);
retrive.onsuccess = function (evt) {
const value = evt.target.result;
result.append(value);
};
cursor.continue();
} else {
console.log('No more entries');
resolve(result);
}
};
});
const setAnEntry = (value) => {
const store = getObjectStore(DB_STORE_NAME, 'readwrite');
store.put(value);
};
const removeAnEntry = (value) => {
const store = getObjectStore(DB_STORE_NAME, 'readwrite');
store.remove(value);
};
return {
all: getAllEntries,
add: setAnEntry,
remove: removeAnEntry,
init: init
};
}
alert("Your browser doesn't support a stable version of IndexedDB. Dairy related features will not be available.");
return {};
})();
Dairy.init()
.then(
result => {
console.log('adding something in the diary');
console.log('... ', Dairy.add({ subject: 'hello', description: 'bluh bluh', date: Date() }));
console.log('show all: ', Dairy.all());
},
error => console.log(error)
);

How to pass dynamic `groupID` from one js file to another js file

I have attached my code for reference, In that I want to pass dynamic groupID from teamgroupapi.js to teamCategoryApi.js
Code is working fine when I try to pass manually groupID from ApiCategory.js file.
File name teamgroupapi.js
import { getGeneratedApi } from '#test/bender-executor-simple-api-generator';
import ApiGroup from '../_support/ApiGroup.js';
const request = require('supertest');
const fs = require('fs');
const assert = require('assert')
const chakram = require ('chakram');
const expect = chakram.expect;
const swaggerPath = process.env.BENDER_SWAGGER_PATH || 'https://api-s10938402.cc-staging.test.com/documentation/api.yaml';
const token = process.env.BENDER_LOGIN_TOKEN || 'JTFihw2GJbJ87duTihoGW3vBi8MErxTbBJsD4dw6k5MsPmfI0J8lsf9-mRFXufFYYMzEVcEdK8kXEi3EVkojHQ';
console.log(`login token is ${token}`);
const apiUrl = 'https://' + (process.env.CC_URL_API || 'api-s10938402.cc-staging.test.com');
const readJsonTestFile = (testfilename) => {
return JSON.parse(fs.readFileSync(testfilename, 'utf8'));
};
describe('Create Group all api generated', () => {
let api;
let groupID;
let apiGroup;
const groupName = "Test_" + new Date().getTime();
const groupName_rename = "Rename_" + new Date().getTime();
//const groupJson = { "name": groupName };
//const grouprenameJson = { "name": groupName_rename };
beforeAll(async () => {
api = await getGeneratedApi(apiUrl, token, swaggerPath);
console.log(api);
apiGroup = new ApiGroup();
});
beforeEach(async () => {
// TODO setup.cleanupDb();
// await setup.gateway();
});
//Create Group API
test('Create Group', async() => {
try
{
jest.setTimeout(10000);
console.log("Create Group");
//const payload = readJsonTestFile('e2e/example.json');
const groupJson = apiGroup.generateCreateGroupJsonObject(groupName);
const createGroup = await api.postTeamGroups(groupJson);
//const listofGroups = JSON.parse(JSON.stringify(createGroup));
//expect(result.response.statusCode).toBe(201);
expect(createGroup).to.have.status(201);
console.log("Create group successfully executed");
} catch(e){
console.log("Failed to create group");
throw e;
}
});
//Get Group API
test('Get Group API', async() => {
try
{
jest.setTimeout(10000);
console.log("Get Created Group");
let foundIndex = -1;
console.log("Running get group and attempting to get ::: " + groupName);
//Check if previously created Group exists using the GET Group API
//Check the response payload and loop through the response to find the workspace that was created earlier
const getGroup = await api.getTeamGroups(false,false);
//const listofGroups = JSON.parse(JSON.stringify(getGroup));
//console.log("list of groups" + getGroup.body.length);
expect(getGroup).to.have.status(200);
for(var i = 0; i < getGroup.body.length;i++){
if((getGroup.body[i].name == groupName) && (getGroup.body[i].id != '') ) {
foundIndex = i;
break;
}
}
groupID = getGroup.body[i].id;
console.log("Group ID ---->>>>" + getGroup.body[i].id);
console.log("Group Name ---->>>>" + getGroup.body[i].name);
expect(foundIndex).to.be.above(-1);
console.log("Get group successfully executed");
} catch(e){
console.log("Failed to get group");
throw e;
}
});
// Rename Group API
test.skip('Rename Group API with Group ID', async()=> {
try
{
jest.setTimeout(10000);
console.log("Rename already created group");
const groupJson = apiGroup.generateCreateGroupJsonObject(groupName_rename);
const apigroup = await api.postTeamGroupsWithGroupID(groupID,groupJson);
expect(apigroup).to.have.status(200);
console.log("Rename group successfully executed");
} catch(e){
console.log("Failed to rename group");
throw e;
}
});
//Delete Group API
test.skip('Delete Group API', async()=> {
try
{
jest.setTimeout(10000);
console.log("Delete Created Group");
console.log("Running delete group and attemptin to delete ::: " + groupID);
const apigroup = await api.deleteTeamGroupsWithGroupID(groupID);
expect(apigroup).to.have.status(200);
console.log("Delete group successfully executed");
} catch(e){
console.log("Failed to delete group");
throw e;
}
});
});
Separate Json Functions for teamgroupapi.js File name ApiGroup.js
class ApiGroup {
constructor()
{
//super();
}
generateCreateGroupJsonObject(groupName) {
return {
"name": groupName
}
}
}
module.exports = ApiGroup;
File name teamCategoryApi.js
import { getGeneratedApi } from '#test/bender-executor-simple-api-generator';
import ApiCategory from '../_support/ApiCategory.js';
import teamgroupapi from './teamgroupapi.js';
const request = require('supertest');
const fs = require('fs');
const assert = require('assert')
const chakram = require ('chakram');
const expect = chakram.expect;
const swaggerPath = process.env.BENDER_SWAGGER_PATH || 'https://api-s10938402.cc-staging.test.com/documentation/api.yaml';
const token = process.env.BENDER_LOGIN_TOKEN || 'JTFihw2GJbJ87duTihoGW3vBi8MErxTbBJsD4dw6k5MsPmfI0J8lsf9-mRFXufFYYMzEVcEdK8kXEi3EVkojHQ';
console.log(`login token is ${token}`);
const apiUrl = 'https://' + (process.env.CC_URL_API || 'api-s10938402.cc-staging.test.com');
const readJsonTestFile = (testfilename) => {
return JSON.parse(fs.readFileSync(testfilename, 'utf8'));
};
describe('Create category all api generated', () => {
let api;
let categoryID;
let apiCategory;
let groupID;
//let teamGroup;
const categoryName = "Test_" + new Date().getTime();
const categoryName_rename = "Rename_" + new Date().getTime();
//const categoryrenameJson = { "name": categoryName_rename };
beforeAll(async () => {
api = await getGeneratedApi(apiUrl, token, swaggerPath);
console.log(api);
apiCategory = new ApiCategory();
//teamGroup = new teamgroupapi();
//console.log(api);
});
beforeEach(async () => {
// TODO setup.cleanupDb();
// await setup.gateway();
});
//Create Category API
test('Create Category', async () => {
jest.setTimeout(20000);
try {
console.log("Create Category");
/*const groupID = teamGroupApi.groupID;
let api = teamGroupApi.api;*/
/*groupID = teamgroupapi.groupID;
console.log(groupID);*/
const categoryJson = apiCategory.generateCreateCategoryJsonObject(categoryName,groupID);
//const categoryJson = { "name": categoryName, "groupId": groupID, "parent": 0 };
const createCategory = await api.postTeamCategories(categoryJson);
//const listofCategories = JSON.parse(JSON.stringify(createCategory));
//expect(result.response.statusCode).toBe(201);
expect(createCategory).to.have.status(201);
console.log("Create category successfully executed");
}
catch (e)
{
console.log("Failed to create category");
throw e;
}
});
//Get Category API
test.skip('Get Category API', async() => {
jest.setTimeout(20000);
try {
console.log("Get Created Category");
let foundIndex = -1;
//const categoryName = "Test_" + new Date().getTime();
console.log("Running get category and attempting to get ::: " + categoryName);
//Check if previously created Group exists using the GET Group API
//Check the response payload and loop through the response to find the workspace that was created earlier
//let api = teamGroupApi.api;
const getCategory = await api.getTeamCategories();
//const listofCategories = JSON.parse(JSON.stringify(apicategory));
//console.log("+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++");
//console.log("list of category" + apicategory.body.length);
expect(getCategory).to.have.status(200);
for(var i = 0; i < getCategory.body.length;i++){
if((getCategory.body[i].name == categoryName) && (getCategory.body[i].id != '') ) {
foundIndex = i;
break;
}
}
categoryID = getCategory.body[i].id;
console.log("Category Name ---->>>>" + getCategory.body[i].id);
console.log("Category Name ---->>>>" + getCategory.body[i].name);
expect(foundIndex).to.be.above(-1);
console.log("Get Category successfully executed");
}
catch (e)
{
console.log("Failed to get category");
throw e;
}
});
//Rename Category API
test.skip('Rename Category API with categoryID', async()=> {
jest.setTimeout(20000);
try {
console.log("Rename already created category");
const renameCategoryJson = apiCategory.renameCreateCategoryJsonObject(categoryName_rename);
//const groupJson = apiGroup.generateCreateGroupJsonObject(groupName_rename);
const apicategory = await api.postTeamCategoriesWithCategoryID(categoryID,renameCategoryJson);
//const apicategory = await api.postTeamCategoriesWithCategoryID(categoryID,categoryrenameJson);
expect(apicategory).to.have.status(200);
console.log("Rename category successfully executed");
}
catch (e)
{
console.log("Failed to Rename category");
throw e;
}
});
//Delete Category API
test.skip('Delete Category API', async()=> {
jest.setTimeout(20000);
try {
console.log("Delete Created Cateory");
console.log("Running delete category and attemptin to delete ::: " + categoryID);
const apicategory = await api.deleteTeamCategoriesWithCategoryID(categoryID);
expect(apicategory).to.have.status(200);
console.log("Delete category successfully executed");
}
catch (e)
{
console.log("Failed to delete category");
throw e;
}
});
});
Separate Json Functions for teamCategory.js File name ApiCategory.js
class ApiCategory {
constructor()
{
//super();
}
generateCreateCategoryJsonObject(categoryName,groupID) {
return{
"name": categoryName,
"groupId": groupID, //if you pass manually groupId here and run the code then code is executed successfully.
"parent": 0
}
}
renameCreateCategoryJsonObject(categoryName_rename) {
return{
"name": categoryName_rename
}
}
}
module.exports = ApiCategory;
A simple pub sub module might help you here
const topics = {};
const hOP = topics.hasOwnProperty;
export default class Events {
/**
*
* #param topic
* #param listener
* #returns {{remove: remove}}
*/
subscribe(topic, listener) {
if (!hOP.call(topics, topic)) topics[topic] = [];
const index = topics[topic].push(listener) - 1;
return {
remove: function() {
delete topics[topic][index];
}
};
}
/**
*
* #param topic
* #param info
*/
publish(topic, info) {
if (!hOP.call(topics, topic)) return;
topics[topic].forEach(function(item) {
item(info != undefined ? info : {});
});
}
}
Create this in a js file somewhere. then import it into each of your js files. When you want to pass the value from one script to another you can first publish in the teamgroupapi file and subscribe to the event in the teamCategoryApi file.
self.events.publish('/eventId', groupId);
events.subscribe('/eventId', (groupId) => {
console.log(groupId);
// do stuff
});
Issue is getting resolve after add this lines to teamgroupapi.js file
export let groupID;
exports.groupID = groupID;
After add above two lines in teamgroupapi.js file.
import { getGeneratedApi } from '#test/bender-executor-simple-api-generator';
import ApiGroup from '../_support/ApiGroup.js';
const request = require('supertest');
const fs = require('fs');
const assert = require('assert')
const chakram = require ('chakram');
const expect = chakram.expect;
const swaggerPath = process.env.BENDER_SWAGGER_PATH || 'https://api-slurmhourly.hourly.cc.altus.bblabs/documentation/api.yaml';
const token = process.env.BENDER_LOGIN_TOKEN || 'ju7WkQItxRMFdMtghlGEVz5CZdC1b4umwLId16591CbK00hWs1a1_lT63cBr8xkvBhPK_vWO-fJTUBdP99LFVw';
console.log(`login token is ${token}`);
const apiUrl = 'https://' + (process.env.CC_URL_API || 'api-slurmhourly.hourly.cc.altus.bblabs');
const readJsonTestFile = (testfilename) => {
return JSON.parse(fs.readFileSync(testfilename, 'utf8'));
};
export var groupID;
describe('Create Group all api generated', () => {
let api;
let apiGroup;
//let groupID;
const groupName = "Test_" + new Date().getTime();
const groupName_rename = "Rename_" + new Date().getTime();
//const groupJson = { "name": groupName };
//const grouprenameJson = { "name": groupName_rename };
beforeAll(async () => {
api = await getGeneratedApi(apiUrl, token, swaggerPath);
console.log(api);
apiGroup = new ApiGroup();
});
beforeEach(async () => {
// TODO setup.cleanupDb();
// await setup.gateway();
});
//Create Group API
test('Create Group', async() => {
try
{
jest.setTimeout(10000);
console.log("Create Group");
const groupJson = apiGroup.generateCreateGroupJsonObject(groupName);
const createGroup = await api.postTeamGroups(groupJson);
expect(createGroup).to.have.status(201);
console.log("Create group successfully executed");
} catch(e){
console.log("Failed to create group");
throw e;
}
});
//Get Group API
test('Get Group API', async() => {
try
{
jest.setTimeout(10000);
console.log("Get Created Group");
let foundIndex = -1;
console.log("Running get group and attempting to get ::: " + groupName);
const getGroup = await api.getTeamGroups(false,false);
expect(getGroup).to.have.status(200);
for(var i = 0; i < getGroup.body.length;i++){
if((getGroup.body[i].name == groupName) && (getGroup.body[i].id != '') ) {
foundIndex = i;
break;
}
}
groupID = getGroup.body[i].id;
console.log("Group ID ---->>>>" + getGroup.body[i].id);
console.log("Group Name ---->>>>" + getGroup.body[i].name);
expect(foundIndex).to.be.above(-1);
console.log("Get group successfully executed");
} catch(e){
console.log("Failed to get group");
throw e;
}
});
// Rename Group API
test.skip('Rename Group API with Group ID', async()=> {
try
{
jest.setTimeout(10000);
console.log("Rename already created group");
const groupJson = apiGroup.generateCreateGroupJsonObject(groupName_rename);
const apigroup = await api.postTeamGroupsWithGroupID(groupID,groupJson);
expect(apigroup).to.have.status(200);
console.log("Rename group successfully executed");
} catch(e){
console.log("Failed to rename group");
throw e;
}
});
//Delete Group API
test.skip('Delete Group API', async()=> {
try
{
jest.setTimeout(10000);
console.log("Delete Created Group");
console.log("Running delete group and attemptin to delete ::: " + groupID);
const apigroup = await api.deleteTeamGroupsWithGroupID(groupID);
expect(apigroup).to.have.status(200);
console.log("Delete group successfully executed");
} catch(e){
console.log("Failed to delete group");
throw e;
}
});
});
exports.groupID = groupID;
In teamCategoryApi.js file add this two lines.
var teamgroupapi = require('./teamgroupapi.js');
groupID = teamgroupapi.groupID;
After Add above two lines in teamCategoryApi.js file issue is getting resolved.
import { getGeneratedApi } from '#test/bender-executor-simple-api-generator';
import ApiCategory from '../_support/ApiCategory.js';
var teamgroupapi = require('./teamgroupapi.js');
const request = require('supertest');
const fs = require('fs');
const assert = require('assert')
const chakram = require ('chakram');
const expect = chakram.expect;
const swaggerPath = process.env.BENDER_SWAGGER_PATH || 'https://api-slurmhourly.hourly.cc.altus.bblabs/documentation/api.json';
const token = process.env.BENDER_LOGIN_TOKEN || 'ju7WkQItxRMFdMtghlGEVz5CZdC1b4umwLId16591CbK00hWs1a1_lT63cBr8xkvBhPK_vWO-fJTUBdP99LFVw';
console.log(`login token is ${token}`);
const apiUrl = 'https://' + (process.env.CC_URL_API || 'api-slurmhourly.hourly.cc.altus.bblabs');
const readJsonTestFile = (testfilename) => {
return JSON.parse(fs.readFileSync(testfilename, 'utf8'));
};
describe('Create category all api generated', () => {
let api;
let categoryID;
let apiCategory;
let groupID;
//let teamGroup;
const categoryName = "Test_" + new Date().getTime();
const categoryName_rename = "Rename_" + new Date().getTime();
//const categoryrenameJson = { "name": categoryName_rename };
beforeAll(async () => {
api = await getGeneratedApi(apiUrl, token, swaggerPath);
console.log(api);
apiCategory = new ApiCategory();
//teamGroup = new teamgroupapi();
//console.log(api);
});
beforeEach(async () => {
// TODO setup.cleanupDb();
// await setup.gateway();
});
//Create Category API
test('Create Category', async () => {
jest.setTimeout(20000);
try {
console.log("Create Category");
groupID = teamgroupapi.groupID;
const categoryJson = apiCategory.generateCreateCategoryJsonObject(categoryName,groupID);
//const categoryJson = { "name": categoryName, "groupId": groupID, "parent": 0 };
const createCategory = await api.postTeamCategories(categoryJson);
//const listofCategories = JSON.parse(JSON.stringify(createCategory));
//expect(result.response.statusCode).toBe(201);
expect(createCategory).to.have.status(201);
console.log("Create category successfully executed");
}
catch (e)
{
console.log("Failed to create category");
throw e;
}
});
//Get Category API
test('Get Category API', async() => {
jest.setTimeout(20000);
try {
console.log("Get Created Category");
let foundIndex = -1;
//const categoryName = "Test_" + new Date().getTime();
console.log("Running get category and attempting to get ::: " + categoryName);
//Check if previously created Group exists using the GET Group API
//Check the response payload and loop through the response to find the workspace that was created earlier
//let api = teamGroupApi.api;
const getCategory = await api.getTeamCategories();
//const listofCategories = JSON.parse(JSON.stringify(apicategory));
//console.log("+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++");
//console.log("list of category" + apicategory.body.length);
expect(getCategory).to.have.status(200);
for(var i = 0; i < getCategory.body.length;i++){
if((getCategory.body[i].name == categoryName) && (getCategory.body[i].id != '') ) {
foundIndex = i;
break;
}
}
categoryID = getCategory.body[i].id;
console.log("Category Name ---->>>>" + getCategory.body[i].id);
console.log("Category Name ---->>>>" + getCategory.body[i].name);
expect(foundIndex).to.be.above(-1);
console.log("Get Category successfully executed");
}
catch (e)
{
console.log("Failed to get category");
throw e;
}
});
//Rename Category API
test('Rename Category API with categoryID', async()=> {
jest.setTimeout(20000);
try {
console.log("Rename already created category");
const renameCategoryJson = apiCategory.renameCreateCategoryJsonObject(categoryName_rename);
//const groupJson = apiGroup.generateCreateGroupJsonObject(groupName_rename);
const apicategory = await api.postTeamCategoriesWithCategoryID(categoryID,renameCategoryJson);
//const apicategory = await api.postTeamCategoriesWithCategoryID(categoryID,categoryrenameJson);
expect(apicategory).to.have.status(200);
console.log("Rename category successfully executed");
}
catch (e)
{
console.log("Failed to Rename category");
throw e;
}
});
//Delete Category API
test('Delete Category API', async()=> {
jest.setTimeout(20000);
try {
console.log("Delete Created Cateory");
console.log("Running delete category and attemptin to delete ::: " + categoryID);
const apicategory = await api.deleteTeamCategoriesWithCategoryID(categoryID);
expect(apicategory).to.have.status(200);
console.log("Delete category successfully executed");
}
catch (e)
{
console.log("Failed to delete category");
throw e;
}
});
});

Categories