I'm new to Graphql and Typescript.
My aim is to unit test Graphql resolvers with Easygraphql-tester. But I'm facing the following error.
TypeError: easygraphql_tester_1.EasyGraphQLTester is not a constructor
Following is my code:
import {EasyGraphQLTester} from "easygraphql-tester";
const schema = `
type FamilyInfo {
id: ID!
isLocal: Boolean!
}
type Query {
getFamilyInfoByIsLocal(isLocal: Boolean!): FamilyInfo
}
`
const query: any = `
query TEST($isLocal: Boolean!) {
getFamilyInfoByIsLocal(isLocal: $isLocal) {
id
isLocal
}
}
`
function getFamilyInfoByIsLocal(__, args, ctx) {
return {
id: 1,
isLocal: args.isLocal
}
}
const resolvers: any = {
Query: {
getFamilyInfoByIsLocal
}
}
const tester = new EasyGraphQLTester(schema, resolvers);
tester.graphql(query, undefined, undefined, { isLocal: false})
.then((result: any) => console.log(result))
.catch((err: any) => console.log(err));
Any idea why I'm facing the constructor error?
The problem lies is in way of importing. As there are no Type Definitions for this package. See Here
const EasyGraphQLTester = require('easygraphql-tester')
Related
In my nextjs-app I have the following page folder structure
- pages
questions-and-answers
[slug].tsx
inside the [slug].tsx I define the getStaticPaths and getStaticProps:
export const getStaticPaths: GetStaticPaths = async () => {
const pathQuery = await request({
query: `
query AllQaPages {
allQaPages {
slug
}
}`,
variables: {},
})
const paths = pathQuery.allQaPages.map(({ slug }) => ({
params: {
slug: slug,
},
}))
return {
paths,
fallback: false,
}
}
export const getStaticProps: GetStaticProps = async ({ params }) => {
const pageRequest = await request({
query: `
query QaPageQuery($slug: String!) {
qaPage(filter: { slug: { eq: $slug } }) {
id
title
slug
qaBlock {
title
id
items {
header
content
id
}
}
}
`
},
variables: { slug: params?.slug },
})
return {
props: {
pageData: pageRequest,
}
}
}
when I run npm run dev it works just fine BUT when I run npm run build, I get the error:
Field 'allQaPages' doesn't exist on type 'Query'
I have no clue why this happens, can someone help me out?
Thanks in advance
i'm getting this error when i run npm run build.
Error occurred prerendering page "/components/comments". Read more:
https://nextjs.org/docs/messages/prerender-error TypeError: Cannot
destructure property 'user' of 'props' as it is undefined.
This is how i'm passing it from parent to child
<CommentComponent
props={{
user,
myComments,
currentComments,
value,
setMsg,
text,
setText,
}}
/>
And this is how i'm receiving it
interface CommentComp {
props: {
user: User;
myComments: MyComments[];
currentComments: (data: User) => void;
value: Date;
setMsg: (data: string) => void;
text: string;
setText: (data: string) => void;
};
}
export default function CommentComponent({ props }: CommentComp): JSX.Element {
const { user, myComments, currentComments, value, setMsg, text, setText } =
props;
}
It works fine when running it locally.
I'm getting the props as
export const getServerSideProps: GetServerSideProps = async (context) => {
const { email } = context.query as { email: string };
const fetchData = await fetch(`http://localhost:3000/api/user/${email}`);
const fetchResult = await fetchData.json();
try {
const userData = fetchResult as {
currUser: User;
notes: MyNotes[];
tasks: MyTasks[];
comments: MyComments[];
reminders: MyReminder[];
};
return {
props: {
user: userData.currUser,
notes: userData.notes,
tasks: userData.tasks,
comments: userData.comments,
reminders: userData.reminders,
},
};
} catch (error) {
console.log(error);
}
};
After the user signed in it redirects to the [email].tsx page
My code looks like this:
interface MutationProps {
username: string;
Mutation: any;
}
export const UseCustomMutation: React.FC<MutationProps> | any = (username: any, Mutation: DocumentNode ) => {
const [functionForDoingAction, { data, loading, error }] = useMutation(
Mutation,
{
variables: {
username,
},
}
);
useEffect(() => {
// fn trigger for change data
functionForDoingAction({
variables: {
username: username,
},
});
console.log(JSON.stringify(data));
console.log(JSON.stringify(error, null, 2));
}, []);
if (loading) return "loading...";
if (error) return `Submission error! ${error.message}`;
return data;
};
export const DisplayUser = () => {
const GET_USER = gql`
mutation GetUser($username: String!) {
getUser(username: $username) {
pfp
username
password
age
CurrentLive
ismod
description
fullname
}
}
`;
const { username }: { username: any } = useParams();
const MyData = UseCustomMutation(username, GET_USER);
console.log(JSON.stringify(MyData));
I wanna a access MyData.pfp but it gives me this error:
TypeError: Cannot read property 'pfp' of undefined
if it matters when i go on e.g. localhost:3000/user/dakepake variable MyData looks like this:
UserProfile.tsx:39 {"getUser":{"pfp":""https://i.pinimg.com/564x/65/25/a0/6525a08f1df98a2e3a545fe2ace4be47.jpg"","username":""dakepake"","password":""mohikanac10"","age":14,"CurrentLive":"""","ismod":false,"description":""this user dont have a bio yet"","fullname":""damjan alimpic"","__typename":"GetUserResponse"}}
How can I fix this?
i fixed this on my own , i just replaced MyData.pfp whit MyData.getUser.pfp and now its working
I'm trying to test my resolvers but i'd like to test each field of the response, here's the code to call the response:
interface Options {
source: string;
variableValues?: Maybe<{ [key: string]: unknown | null }>;
}
let schema: GraphQLSchema;
const gCall = async ({
source,
variableValues,
}: Options): Promise<ExecutionResult> => {
if (!schema) {
schema = await createSchema();
}
return graphql({
schema,
source,
variableValues,
});
};
export default gCall;
And that's the code to test the resolver:
let connection: Connection;
const challengeMutation = `
mutation CreateChallenge($data: CreateChallengeInput!) {
createChallenge(data: $data) {
id
name
category
startDate
endDate
goal
description
}
}
`;
describe('Create Challenge', () => {
beforeAll(async () => {
connection = await databaseTestConnection();
await connection.createQueryBuilder().delete().from(Challenge).execute();
});
afterAll(async () => {
await connection.createQueryBuilder().delete().from(Challenge).execute();
await connection.close();
});
it('should create challenge', async () => {
const challenge = {
name: 'some awesome name',
category: 'distância',
startDate: new Date(2020, 7, 4).toISOString(),
endDate: new Date(2020, 7, 5).toISOString(),
goal: 5000,
description: 'some excelent challenge description',
};
const response = await gCall({
source: challengeMutation,
variableValues: {
data: challenge,
},
});
expect(response).toMatchObject({
data: {
createChallenge: {
name: challenge.name,
category: challenge.category,
startDate: challenge.startDate,
endDate: challenge.endDate,
goal: challenge.goal,
description: challenge.description,
},
},
});
});
});
What I'd like to do is test the fields separately, like this:
expect(response.data.createChallenge.name).toEqual(challenge.name);
But I'm getting the following error when I try to execute the above code:
Object is possibly 'null' or 'undefined'.
What can I do to solve this error and to make this test better?
Object is possibly 'null' or 'undefined'.
TypeScript warns you that the response data might not exist as the graphql "server" might return error instead. So you should use ! operator to assert it's not null.
You should also do that after checking it's not undefined with expect().
I'm new in graphql and I am trying to integrate an authentication/authorization system in my project. I found an example on Medium, but I do not understand how a guard communicates with a resolver. If someone knows, I will be very grateful.
import { ApolloServer } from 'apollo-server';
import gql from 'graphql-tag';
import { tradeTokenForUser } from './auth-helpers';
const HEADER_NAME = 'authorization';
const typeDefs = gql`
type Query {
me: User
serverTime: String
}
type User {
id: ID!
username: String!
}
`;
const resolvers = {
Query: {
me: authenticated((root, args, context) => context.currentUser),
serverTime: () => new Date(),
},
User: {
id: user => user._id,
username: user => user.username,
},
};
const server = new ApolloServer({
typeDefs,
resolvers,
context: async ({ req }) => {
let authToken = null;
let currentUser = null;
try {
authToken = req.headers[HEADER_NAME];
if (authToken) {
currentUser = await tradeTokenForUser(authToken);
}
} catch (e) {
console.warn(`Unable to authenticate using auth token: ${authToken}`);
}
return {
authToken,
currentUser,
};
},
});
server.listen().then(({ url }) => {
console.log(`🚀 Server ready at ${url}`);
});
export const authenticated = next => (root, args, context, info) => {
if (!context.currentUser) {
throw new Error(`Unauthenticated!`);
}
return next(root, args, context, info);
};
I do not understand what "next" parameter does and why as an argument when this guard is called I have to return a value?
authenticated is higher-order function that makes the code DRY. next is a callback that is used as a predicate.
It's a DRYer way to write:
...
me: (root, args, context) => {
if (!context.currentUser) {
throw new Error(`Unauthenticated!`);
}
return context.currentUser;
)
...