Method "Astronomy/execute" not found in meteor - meteor

Okay, I build Game DB schema using astronomy package in meteor.
Then I try to add method to it by extending it in server. (server/gamehandle.js)
import {Game} from '../imports/db/game'
import {DDP} from 'meteor/ddp-client'
Game.extend({
meteorMethods: {
AddNewGame(judul){
const invocation = DDP._CurrentInvocation.get()
this.namaGame = judul
this.creator = invocation.userId
this.createdAt = new Date()
return this.save()
}
}
})
But when I try to run the method in app client using callMethod it throw an error that astronomy/execute not found 404.
This the component using it
import {Game} from '../../../db/game'
export function NewGameList(props){
const { isOpen, onOpen, onClose } = useDisclosure()
const [judul, setJudul] = useState('')
const [hasil, setHasil] = useState(null)
const judulChange = (e) => setJudul(e.target.value)
const AddGame = new Game()
const handleSubmit = (e) => {
e.preventDefault()
AddGame.callMethod('AddNewGame', judul, (err, result) => {
result ? setHasil(result) : setHasil(err.message)
console.log(err)
})
}
...
So enlight me, what thing I do wrong?

Finally found the solution from meteor slack.
Just need to imports my db file to main js file in server.

Related

Nextjs 13.0.2 and Ethers why is my Provider undefined?

I'm trying to access the ethers provider like this in Nextjs 13.0.1:
import { ethers } from "ethers";
export const signMessage = () => {
const provider = new ethers.providers.Web3Provider(window.ethereum);
const signer = provider.getSigner();
try {
signer.signMessage("Hey hey").then((result) => {
console.log(result);
});
} catch (error) {
// handle error
console.log(error);
}
};
But it always gives me the error:
Unhandled Runtime Error
TypeError: Cannot read properties of undefined (reading 'Web3Provider')
I've tried different providers but always get the error message above.
Someone knows why it's working for Nextjs 12 but not for Next 13?
I think you are using version 6 in next13. if you install
"ethers": "^5.6.4",
in next-13, it will work.
I think you previously had next-12 project with version 5, and now installing new version on next-13
in ethers v6 all of those
export {
getDefaultProvider,
Block, FeeData, Log, TransactionReceipt, TransactionResponse,
AbstractSigner, NonceManager, VoidSigner,
AbstractProvider,
FallbackProvider,
JsonRpcApiProvider, JsonRpcProvider, JsonRpcSigner,
BrowserProvider,
AlchemyProvider, AnkrProvider, CloudflareProvider, EtherscanProvider,
InfuraProvider, PocketProvider, QuickNodeProvider,
IpcSocketProvider, SocketProvider, WebSocketProvider,
EnsResolver,
Network
} from "./providers/index.js";
are imported like this
import { BrowserProvider } from "ethers";
const providerr = new BrowserProvider(window.ethereum);
this is how I set a component to connect
const Test = () => {
const [provider, setProvider] = useState();
useEffect(() => {
const browserProvider = new BrowserProvider(window.ethereum);
setProvider(browserProvider);
}, []);
const connect = async () => {
await provider.send("eth_requestAccounts");
};
return (
<div>
<button onClick={connect}>connect</button>
</div>
);
};
export default Test;
If you are using "ethers": "^6.0.2" like me then use this :
const web3Provider = new ethers.BrowserProvider(window.ethereum);
Also then getting signer you should remember that web3Provider.getSigner() will return a promise so use await or then
const signer = await web3Provider.getSigner();
Check more on ethers documentation

PromiseĀ {<pending>} Graphql, and strapi with nextjs

With GraphQL and nextjs, I'm trying to retrieve some data from strapi.
When I try to access these data from the other file and display them on the UI, I get this error PromiseĀ {} in console.log.
This is what i tried
sliderAdapter.js
import { fetchSlider } from "./apiClient";
export const sliderAdapter = async (data, locale, url) => {
const sl = await fetchSlider();
const deepDownSlides = sl.data?.slides?.data;
if (deepDownSlides.length > 0) {
const slider = deepDownSlides[0]?.attributes?.slider;
// console.log("slider", slider);
return slider;
}
// This code is working but not properly, just return the data into the console.
return "";
};
fetchSlider is the file where i put the query.
Next:
import { sliderAdapter } from "../../lib/sliderAdapter";
const Slider = (data) => {
const slide= sliderAdapter(data)
console.log("slide", slide)
If anyone knows or can find the issues, plz let me know :)
Your function is asynchronous so you have to retrieve the value once the promise is resolved
sliderAdapter(data).then(slide=>console.log(slide))

next.js API routes share database

I want to use next.js routes api as a backend service and serve database result in json format. I see, there is no way to keep database up and running since all files located at pages/api/ it's ephemeral
Below it's my code
import { models } from "../models/index"
export default async function handler(req, res) {
const User = models.User
try {
const result = await User.findAll()
return res.json({ result })
} catch (err) {
console.error("Error occured ", err)
return res.json({ result: [] })
}
}
anyone who has encountered this problem?
The only possible way that I found is to use node js server and attach database model to request object. By doing this we pass database conection/models through routes api
my node.js server
const express = require("express")
const { sequelize } = require("./models/index")
const next = require("next")
const dev = process.env.NODE_ENV !== "production"
const app = next({ dev })
const handle = app.getRequestHandler()
const appExpress = express()
app.prepare().then(() => {
appExpress.use(express.json())
appExpress.get("*", (req, res) => {
req.db = sequelize
handle(req, res)
})
appExpress.listen(5000, () => console.log("> Ready on http://localhost:5000"))
}).catch((ex) => {
console.error(ex.stack)
process.exit(1)
})
my routes api file changed to
export default async function handler(req, res) {
const User = req.db.models.User
try {
const result = await User.findAll()
return res.json({ result })
} catch (err) {
console.error("Error occured ", err)
return res.json({ result: [] })
}
}
with these changes the database is always up and running and used from all routes api files.
I tested and work like charm

Redux testing: Actions must be plain objects. Use custom middleware for async actions

I have a Redux app and it is working perfectly without any errors. Now I am trying to test it with Enzyme, Jest and Sinon:
it('calls constructor', () => {
sinon.spy(SavedVariantsComponent.prototype, 'constructor')
const store = configureStore()(STATE1)
wrapper = mount(<SavedVariantsComponent store={store} match={{ params: {} }} />)
expect(SavedVariantsComponent.prototype.constructor).toHaveProperty('callCount', 1)
})
In SavedVariantsComponent I have mapDispatchToProps:
const mapDispatchToProps = (dispatch, ownProps) => {
return {
onSubmit: (updates) => {
dispatch(updateSavedVariantTable(updates))
const { match, analysisGroup } = ownProps
const { familyGuid, variantGuid, tagArray, gene } = match.params
const familyGuids = familyGuid ? [familyGuid] : (analysisGroup || {}).familyGuids
const combineVariants = /combined_variants/.test(match.url)
dispatch(loadSavedVariants(combineVariants, familyGuids, variantGuid, tagArray, gene))
},
loadSavedVariants: (...args) => dispatch(loadSavedVariants(...args)),
}
}
And loadSavedVariants look like that:
export const loadSavedVariants = (combineVariants, familyGuids, variantGuid, tagArray, gene = '') => {
return (dispatch, getState) => {
...
...
and the error while running jest is:
Actions must be plain objects. Use custom middleware for async actions.
Which makes an HTTP Request that may not work in the current case. How to fix this error? I need to test that the constructor was called, but later on will also need to see how the inner Components are rendered, so need to have mount there. I suppose I am doing something wrong in testing and not in the real code since the latter is working without any errors, warnings or issues.
You probably need to configure your mock store to work with redux-thunk. See: https://github.com/dmitry-zaets/redux-mock-store#asynchronous-actions
import configureStore from 'redux-mock-store'
import thunk from 'redux-thunk'
const middlewares = [thunk] // add your middlewares like `redux-thunk`
const mockStore = configureStore(middlewares)

How do you unit test a firebase function wrapped with express?

With firebase functions, you can utilize express to achieve nice functionality, like middleware etc. I have used this example to get inspiration of how to write https firebase functions, powered by express.
However, my issue is that the official firebase documentation on how to do unit testing, does not include a https-express example.
So my question is how to unit test the following function (typescript)?:
// omitted init. of functions
import * as express from 'express';
const cors = require('cors')({origin: true});
const app = express();
app.use(cors);
// The function to test
app.get('helloWorld, (req, res) => {
res.send('hello world');
return 'success';
});
exports.app = functions.https.onRequest(app);
This works with Jest
import supertest from 'supertest'
import test from 'firebase-functions-test'
import sinon from 'sinon'
import admin from 'firebase-admin'
let undertest, adminInitStub, request
const functionsTest = test()
beforeAll(() => {
adminInitStub = sinon.stub(admin, 'initializeApp')
undertest = require('../index')
// inject with the exports.app methode from the index.js
request = supertest(undertest.app)
})
afterAll(() => {
adminInitStub.restore()
functionsTest.cleanup()
})
it('get app', async () => {
let actual = await request.get('/')
let { ok, status, body } = actual
expect(ok).toBe(true)
expect(status).toBeGreaterThanOrEqual(200)
expect(body).toBeDefined()
})
You can use supertest paired with the guide from Firebase. Below is a very basic example of testing your app, however, you can make it more complex/better by integrating mocha.
import * as admin from 'firebase-admin'
import * as testFn from 'firebase-functions-test'
import * as sinon from 'sinon'
import * as request from 'supertest'
const test = testFn()
import * as myFunctions from './get-tested' // relative path to functions code
const adminInitStub = sinon.stub(admin, 'initializeApp')
request(myFunctions.app)
.get('/helloWorld')
.expect('hello world')
.expect(200)
.end((err, res) => {
if (err) {
throw err
}
})
Would something like mock-express work for you? It should allow you to test paths without actually forcing you to make the express server.
https://www.npmjs.com/package/mock-express
I've gotten this to work using firebase-functions-test and node-mocks-http.
I have this utility class FunctionCaller.js :
'use strict';
var httpMocks = require('node-mocks-http');
var eventEmitter = require('events').EventEmitter;
const FunctionCaller = class {
constructor(aYourFunctionsIndex) {
this.functions_index = aYourFunctionsIndex;
}
async postFunction(aFunctionName,aBody,aHeaders,aCookies) {
let url = (aFunctionName[0]=='/') ? aFunctionName : `/${aFunctionName}`;
let options = {
method: 'POST',
url: url,
body: aBody
};
if (aHeaders)
options.headers = aHeaders;
if (aCookies) {
options.cookies = {};
for (let k in aCookies) {
let v = aCookies[k];
if (typeof(v)=='string') {
options.cookies[k] = {value: v};
} else if (typeof(v)=='object') {
options.cookies[k] = v;
}
}
}
var request = httpMocks.createRequest(options);
var response = httpMocks.createResponse({eventEmitter: eventEmitter});
var me = this;
await new Promise(function(resolve){
response.on('end', resolve);
if (me.functions_index[aFunctionName])
me.functions_index[aFunctionName](request, response);
else
me.functions_index.app(request, response);
});
return response;
}
async postObject(aFunctionName,aBody,aHeaders,aCookies) {
let response = await this.postFunction(aFunctionName,aBody,aHeaders,aCookies);
return JSON.parse(response._getData());
}
async getFunction(aFunctionName,aParams,aHeaders,aCookies) {
let url = (aFunctionName[0]=='/') ? aFunctionName : `/${aFunctionName}`;
let options = {
method: 'GET',
url: url,
query: aParams // guessing here
};
if (aHeaders)
options.headers = aHeaders;
if (aCookies) {
options.cookies = {};
for (let k in aCookies) {
let v = aCookies[k];
if (typeof(v)=='string') {
options.cookies[k] = {value: v};
} else if (typeof(v)=='object') {
options.cookies[k] = v;
}
}
}
var request = httpMocks.createRequest(options);
var response = httpMocks.createResponse({eventEmitter: eventEmitter});
var me = this;
await new Promise(function(resolve){
response.on('end', resolve);
if (me.functions_index[aFunctionName])
me.functions_index[aFunctionName](request, response);
else
me.functions_index.app(request, response);
});
return response;
}
async getObject(aFunctionName,aParams,aHeaders,aCookies) {
let response = await this.getFunction(aFunctionName,aParams,aHeaders,aCookies);
return JSON.parse(response._getData());
}
};
module.exports = FunctionCaller;
and my app is mounted as app :
exports.app = functions.https.onRequest(expressApp);
and my firebase.json contains :
"rewrites": [
:
:
:
{
"source": "/path/to/function", "function": "app"
}
]
In my test file at the top I do :
const FunctionCaller = require('../FunctionCaller');
let fire_functions = require('../index');
const fnCaller = new FunctionCaller(fire_functions);
and then in the test I do :
let response = await fnCaller.postFunction('/path/to/function',anObject);
and it calls my function with anObject as request.body and returns the response object.
I'm using node 8 on Firebase to get async/await etc.
For local & no-network unit tests, you could refactor the app.get("helloWorld", ...) callback into a separate function and call it with mock objects.
A general approach would be something like this:
main.js:
// in the Firebase code:
export function helloWorld(req, res) { res.send(200); }
app.get('helloWorld', helloWorld);
main.spec.js: using jasmine & sinon
// in the test:
import { helloWorld } from './main.js';
import sinon from 'sinon';
const reqMock = {};
const resMock = { send: sinon.spy() };
it('always responds with 200', (done) => {
helloWorld(reqMock, resMock);
expect(resMock.send.callCount).toBe(1);
expect(resMock.send).toHaveBeenCalledWith(200);
});
Testing is about building up confidence or trust.
I would start by Unit Testing the function in FireBase. Without more requirements defined, I would follow the documentation. Once those Unit Tests pass you can consider what type of testing you want at the Express level. Keeping in mind that you have already tested the function, the only thing to test at the Express level is if the mapping is correct. A few tests at that level should be sufficient to ensure that the mappings have not become "stale" as a result of some set of changes.
If you want to test the Express level and above without having to involve the DB, then you would look at a mocking framework to act like the database for you.
Hope this helps you think about what tests you need.
You can use postman application for unit test.
Enter following url with your project name
https://us-central1-your-project.cloudfunctions.net/hello
app.get('/hello/',(req, res) => {
res.send('hello world');
return 'success';
});

Resources