How to use AzureLogger in Azure Communication Services - javascript

The example code snippet # https://learn.microsoft.com/en-us/azure/communication-services/concepts/troubleshooting-info?tabs=csharp%2Cjavascript%2Cdotnet is incomplete. I'm not familiar enough with JavaScript modules to get this working. I've added the module to package.json ("#azure/logger": "1.0.1"). When I execute my code example, I receive the following exception:
Uncaught TypeError: this._azureLogger.info is not a function
documentation example:
import { AzureLogger } from '#azure/logger';
AzureLogger.verbose = (...args) => { console.info(...args); }
AzureLogger.info = (...args) => { console.info(...args); }
AzureLogger.warning = (...args) => { console.info(...args); }
AzureLogger.error = (...args) => { console.info(...args); }
callClient = new CallClient({logger: AzureLogger});
my failed attempt:
import { AzureLogger } from '#azure/logger';
const logger = require('#azure/logger');
logger.setLogLevel('verbose');
const callClientOptions: CallClientOptions = { logger };
Can anyone share a working example of this code?

Scott, thank you for raising this up. The product group is working on updating the document you linked for a long term fix. In regards to a short term fix to get you unblocked, can you please try the below sample?
We apologize for the inconvenience that this caused and look forward to your verification of the below sample.
import { createClientLogger, setLogLevel } from '#azure/logger';
const logger = createClientLogger('ACS');
setLogLevel('verbose');
logger.verbose.log = (...args) => { console.log(...args); };
logger.info.log = (...args) => { console.info(...args) ; };
logger.warning.log = (...args) => { console.warn(...args); };
logger.error.log = (...args) => { console.error(...args); };
const options = { logger: logger };
this.callClient = new CallClient(options);

Related

NodeJS: My jest spyOn function is not being called

I don't understand why my spy is not being used. I have used this code elsewhere and it has worked fine.
Here is my test:
const {DocumentEngine} = require('../documentEngine')
const fileUtils = require('../utils/fileUtils')
const request = {...}
const fieldConfig = {...}
test('If the Carbone addons file is not found, context is built with the carboneAddons property as an empty object', async () => {
const expectedResult = {
carboneAddons: {},
}
const fileExistSpy = jest
.spyOn(fileUtils, 'checkFileExists')
.mockResolvedValue(false)
const result = await docEngine.buildContext(request, fieldConfig)
expect(fileExistSpy).toHaveBeenCalledTimes(1)
})
Here is the code that it is being tested:
async function buildContextForLocalResources(request, fieldConfig) {
/* other code */
const addonFormatters = await getCarboneAddonFormatters()
const context = {
sourceJson,
addonFormatters,
documentFormat,
documentTemplateId,
documentTemplateFile,
responseType,
jsonTransformContext
}
return context
}
async function getCarboneAddonFormatters() {
const addOnPath = path.resolve(
docConfig.DOC_GEN_RESOURCE_LOCATION,
'library/addon-formatters.js'
)
if (await checkFileExists(addOnPath)) {
logger.info('Formatters found and are being used')
const {formatters} = require(addOnPath)
return formatters
}
logger.info('No formatters were found')
return {}
}
This is the code from my fileUtils file:
const fs = require('fs/promises')
async function checkFileExists(filePath) {
try {
await fs.stat(filePath)
return true
} catch (e) {
return false
}
}
My DocumentEngine class calls the buildContext function which in turn calls the its method getCarboneAddonFormatters. The fileUtils is outside of DocumentEngine class in a utilities folder. The original code I had this working on was TypeScript as opposed to this which is just NodeJS Javascript. The config files for both are the same. When I try to step through the code (VSCode debugger), as soon as I hit the line with await fs.stat(filePath) in the checkFileExists function, it kicks me out of the test and moves on to the next test - no error messages or warnings.
I've spent most of the day trying to figure this out. I don't think I need to do an instance wrapper for the documentEngine, because checkFileExists is not a class member, and that looks like a React thing...
Any help in getting this to work would be appreciated.

How to display Metaplex NFT in React using #metaplex/js and programs.metadata.Metadata

I am trying to run this 'getting started' example from the docs. However I think there's been a change and programs.metadata.Metadata (shown there) no longer works.
https://docs.metaplex.com/sdk/js/getting-started
They suggest this:
import { Connection, programs } from '#metaplex/js';
const connection = new Connection('devnet');
const tokenPublicKey = 'Gz3vYbpsB2agTsAwedtvtTkQ1CG9vsioqLW3r9ecNpvZ';
const run = async () => {
try {
const ownedMetadata = await programs.metadata.Metadata.load(connection, tokenPublicKey);
console.log(ownedMetadata);
} catch {
console.log('Failed to fetch metadata');
}
};
run();
I have this in my React app:
import { Connection, programs } from '#metaplex/js';
const connection = new Connection('devnet');
const tokenPublicKey = 'Gz3vYbpsB2agTsAwedtvtTkQ1CG9vsioqLW3r9ecNpvZ';
const run = async () => {
try {
const ownedMetadata = await programs.metadata.Metadata.load(connection, tokenPublicKey);
console.log(ownedMetadata);
} catch(error) {
console.log('Failed to fetch metadata');
console.log(error);
}
};
function App() {
return (
<div className="App">
<p onClick={run}>would be cool if it worked</p>
</div>
);
}
export default App;
I get an error as though programs.metadata.Metadata doesn't exist - "Cannot read properties of undefined (reading 'Metadata')". I even took this out of React and did a plain node script to just run the example code, which fails in the same way.
Any idea on how I could fix this?
For users that find this question via search:
There is now a better solution than using #metaplex-foundation/mpl-token-metadata directly. Have a look at #metaplex/js-next findByMint
Those lines should be all you need. imageUrl would be the image path.
import { Metaplex } from "#metaplex-foundation/js-next";
import { Connection, clusterApiUrl } from "#solana/web3.js";
const connection = new Connection(clusterApiUrl("mainnet-beta"));
const metaplex = new Metaplex(connection);
const mint = new PublicKey("ATe3DymKZadrUoqAMn7HSpraxE4gB88uo1L9zLGmzJeL");
const nft = await metaplex.nfts().findByMint(mint);
const imageUrl = nft.metadata.image;

Unable to implement singleton patten in javascript

I am trying to implement a singleton pattern for the fastify instance. My code is as follows :-
const { createFastifyServer: server } = require("../app");
const getFastifyInstance = (() => {
let fastify;
return {
fastifyInstance: async () => {
if (!fastify) {
console.log("Called")
fastify = server();
await fastify.ready();
}
return fastify
}
}
})();
const { fastifyInstance } = getFastifyInstance
module.exports = fastifyInstance
Now wherever I am importing the code in a different file, the console prints "Called" each time it's imported in a new file, but shouldn't that be only once if singleton pattern was correctly implemented. Any idea what am I doing wrong?

Print out Function (Debug Redux State and Actions without Redux Dev Tools)

I am doing some research into how Slack uses Redux. I am running custom Javascript on the page using the Chrome extension CJS.
I log the action and state changes. When the action is a function I can't log the function correctly.
Here is an excerpt from the console log:
...
[AP] store dispatch called: function d(e,n){return t(e,n,r)}
[AP] teamStore dispatch called: {"type":"[21] Navigate to a route","payload":{"routeName":"ROUTE_ENTITY","params":{"teamId":"TS6QSK7PA","entityId":"DU52E70NB"}},"error":false}
...
The code where I print the function is:
console.log("[AP] store dispatch called: " + (JSON.stringify(action) || action.toString()));
Here is full code code:
const teamStates = [];
const states = [];
let base;
let teamStore;
let store;
function subscribeToStores() {
const reactRoot = document.getElementsByClassName('p-client_container')[0];
try {
base = reactRoot._reactRootContainer._internalRoot.current
} catch (e) {
console.log('[AP] Could not find React Root');
}
if (!base) {
setTimeout(() => {
subscribeToStores();
}, 1);
} else {
console.log('[AP] Found React Root');
while (!store) {
try {
store = base.pendingProps.store;
} catch (e) {}
base = base.child
}
console.log('[AP] Found store');
console.log(JSON.stringify(store.getState()));
states.push(store.getState());
while (!teamStore) {
try {
teamStore = base.pendingProps.teamStore;
} catch (e) {}
base = base.child
}
console.log('[AP] Found teamStore');
console.log(JSON.stringify(teamStore.getState()));
teamStates.push(teamStore.getState());
var unsubscribe1 = teamStore.subscribe(() => {
teamStates.push(teamStore.getState());
console.log("[AP] teamStates length:" + teamStates.length);
console.log(JSON.stringify(teamStore.getState()));
})
var rawDispatchTeamStore = teamStore.dispatch;
teamStore.dispatch = (action) => {
console.log("[AP] teamStore dispatch called: " + (JSON.stringify(action) || action.toString()));
rawDispatchTeamStore(action);
}
var unsubscribe2 = store.subscribe(() => {
states.push(store.getState());
console.log("[AP] states length:" + states.length);
console.log(JSON.stringify(store.getState()));
})
var rawDispatchStore = store.dispatch;
store.dispatch = (action) => {
console.log("[AP] store dispatch called: " + (JSON.stringify(action) || action.toString()));
rawDispatchStore(action);
}
}
}
subscribeToStores();
I'm not sure how better you could log that function. Since the code is most likely minified, you won't be able to get its original name, except maybe through sourcemaps. What more information did you want?
That said, it's pretty strange to dispatch a function to begin with. I would be more curious how the reducer for store is handling functions since, normally, actions are supposed to be objects with a type property.

Testing with Jest - reset/clear variables set by tested function and catching console logs

I'm learning writing unit test with Jest.
I use typescript, but it shouldn't be a problem here. Feel free to provide examples with pure JavaScript.
Until now I have function:
const space = String.fromCharCode(0x0020);
const rocket = String.fromCharCode(0xD83D, 0xDE80);
let notified: boolean = false;
export const logHiring = (message: string = "We're hiring!", emoji: string = rocket) => {
if (!notified) {
console.info(
[message, emoji]
.filter((e) => e)
.join(space)
);
notified = true;
}
};
Yes, function should log to console just one message per initialization.
And not really working tests:
import {logHiring} from "../index";
const rocket = String.fromCharCode(0xD83D, 0xDE80);
// First test
test("`logHiring` without arguments", () => {
let result = logHiring();
expect(result).toBe(`We're hiring! ${rocket}`);
});
// Second test
test("`logHiring` with custom message", () => {
let result = logHiring("We are looking for employees");
expect(result).toBe(`We are looking for employees ${rocket}`);
});
// Third test
test("`logHiring` multiple times without arguments", () => {
let result = logHiring();
result = logHiring();
result = logHiring();
expect(result).toBe(`We're hiring! ${rocket}`);
});
I have two problems:
How can I test console logs? I've tried spyOn without succes.
How can I reset internal (from function) notified variable for each test?
How can I test console logs? I've tried spyOn without succes.
https://facebook.github.io/jest/docs/en/jest-object.html#jestspyonobject-methodname
const spy = jest.spyOn(console, 'log')
logHiring();
expect(spy).toHaveBeenCalledWith("We're hiring!")
How can I reset internal (from function) notified variable for each test?
export a getter/setter function like
// index.js
export const setNotified = (val) => { notified = val }
export const getNotified = _ => notified
// index.test.js
import { getNotified, setNotified } from '..'
let origNotified = getNotified()
beforeAll(_ => {
setNotified(/* some fake value here */)
...
}
afterAll(_ => {
setNotified(origNotified)
...
}

Categories

Resources