@snowtop/ent-graphql-tests
Version:
easy ways to test ent and graphql
1,208 lines (1,207 loc) • 38.1 kB
JavaScript
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.names = void 0;
const express_1 = __importDefault(require("express"));
const graphql_1 = require("graphql");
const graphql_upload_1 = require("graphql-upload");
const fs = __importStar(require("fs"));
const supertest_1 = __importDefault(require("supertest"));
const index_1 = require("./index");
const graphql_2 = require("@snowtop/ent/graphql");
const auth_1 = require("@snowtop/ent/auth");
const graphql_helix_1 = require("graphql-helix");
test("simplest query", async () => {
const schema = new graphql_1.GraphQLSchema({
query: new graphql_1.GraphQLObjectType({
name: "RootQueryType",
fields: {
hello: {
type: graphql_1.GraphQLString,
resolve() {
return "world";
},
},
},
}),
});
const cfg = {
schema: schema,
args: {},
root: "hello",
// debugMode: true,
};
// root query
await (0, index_1.expectQueryFromRoot)(cfg, ["", "world"]);
});
class Address {
}
var DayOfWeek;
(function (DayOfWeek) {
DayOfWeek["Sunday"] = "Sunday";
DayOfWeek["Monday"] = "Monday";
DayOfWeek["Tuesday"] = "Tuesday";
DayOfWeek["Wednesday"] = "Wednesday";
DayOfWeek["Thursday"] = "Thursday";
DayOfWeek["Friday"] = "Friday";
DayOfWeek["Saturday"] = "Saturday";
})(DayOfWeek || (DayOfWeek = {}));
class User {
}
class Contact {
}
exports.names = [
{
firstName: "Robb",
lastName: "Stark",
},
{
firstName: "Sansa",
lastName: "Stark",
},
{
firstName: "Arya",
lastName: "Stark",
},
{
firstName: "Bran",
lastName: "Stark",
},
{
firstName: "Rickon",
lastName: "Stark",
},
{
firstName: "Jon",
lastName: "Snow",
},
];
const NickNames = ["Lord Snow", "The Prince That was Promised"];
const weekends = [DayOfWeek.Saturday, DayOfWeek.Sunday];
const weekendsGQL = weekends.map((v) => v.toUpperCase());
function getUser(id) {
const result = new User();
result.id = id;
result.firstName = "Jon";
result.lastName = "Snow";
result.daysOff = weekends;
let num = parseInt(id, 0) || 0;
if (num % 2 == 0) {
result.address = {
id: "23",
street: "1 main street",
city: "San Francisco",
state: "CA",
zipCode: "94102",
};
}
if (num % 10 == 0) {
result.contacts = ({ first, domain, lastName }) => {
let ret = [];
if (domain || lastName) {
for (let i = 0; i < exports.names.length; i++) {
const parts = domain ? domain.split(".") : [];
const name = exports.names[i];
if (name.lastName === lastName || name.lastName === parts[0]) {
ret.push({
firstName: name.firstName,
lastName: name.lastName,
emailAddress: `${name.firstName}@${name.lastName}.com`,
phoneNumber: "415-222-3322",
id: (i + 1000).toString(),
});
}
}
return ret;
}
if (first === undefined) {
first = exports.names.length;
}
for (let i = 0; i < first; i++) {
let idx = i % exports.names.length;
let name = exports.names[idx];
ret.push({
firstName: name.firstName,
lastName: name.lastName,
emailAddress: `${name.firstName}@${name.lastName}.com`,
phoneNumber: "415-222-3322",
id: (i + 1000).toString(),
});
}
return ret;
};
}
if (num === 1001) {
result.nicknames = NickNames;
}
return result;
}
function editUser(id, user) {
const result = getUser(id);
for (const k in user) {
result[k] = user[k];
}
return result;
}
const addressType = new graphql_1.GraphQLObjectType({
name: "Address",
fields: {
id: {
type: new graphql_1.GraphQLNonNull(graphql_1.GraphQLID),
},
street: {
type: new graphql_1.GraphQLNonNull(graphql_1.GraphQLString),
},
city: {
type: new graphql_1.GraphQLNonNull(graphql_1.GraphQLString),
},
state: {
type: new graphql_1.GraphQLNonNull(graphql_1.GraphQLString),
},
zipCode: {
type: new graphql_1.GraphQLNonNull(graphql_1.GraphQLString),
},
apartment: {
type: graphql_1.GraphQLString,
},
},
interfaces: [graphql_2.GraphQLNodeInterface],
});
const contactType = new graphql_1.GraphQLObjectType({
name: "ContactType",
fields: {
id: {
type: new graphql_1.GraphQLNonNull(graphql_1.GraphQLID),
},
firstName: {
type: graphql_1.GraphQLString,
},
lastName: {
type: graphql_1.GraphQLString,
},
emailAddress: {
type: graphql_1.GraphQLString,
},
phoneNumber: {
type: graphql_1.GraphQLString,
},
},
interfaces: [graphql_2.GraphQLNodeInterface],
});
const dayOfWeekType = new graphql_1.GraphQLEnumType({
name: "DayOfWeek",
values: {
MONDAY: {
value: DayOfWeek.Monday,
},
TUESDAY: {
value: DayOfWeek.Tuesday,
},
WEDNESDAY: {
value: DayOfWeek.Wednesday,
},
THURSDAY: {
value: DayOfWeek.Thursday,
},
FRIDAY: {
value: DayOfWeek.Friday,
},
SATURDAY: {
value: DayOfWeek.Saturday,
},
SUNDAY: {
value: DayOfWeek.Sunday,
},
},
});
const userType = new graphql_1.GraphQLObjectType({
name: "User",
fields: {
id: {
type: new graphql_1.GraphQLNonNull(graphql_1.GraphQLID),
},
firstName: {
type: graphql_1.GraphQLString,
},
lastName: {
type: graphql_1.GraphQLString,
},
address: {
type: addressType,
},
contacts: {
type: new graphql_1.GraphQLList(contactType),
args: {
first: {
type: graphql_1.GraphQLInt,
},
domain: {
type: graphql_1.GraphQLString,
},
lastName: {
type: graphql_1.GraphQLString,
},
},
},
nicknames: {
type: new graphql_1.GraphQLList(new graphql_1.GraphQLNonNull(graphql_1.GraphQLString)),
},
daysOff: {
type: new graphql_1.GraphQLList(new graphql_1.GraphQLNonNull(dayOfWeekType)),
},
},
interfaces: [graphql_2.GraphQLNodeInterface],
isTypeOf(obj, context) {
const isUser = obj instanceof User;
return context.async ? Promise.resolve(isUser) : isUser;
},
});
const userPayloadType = new graphql_1.GraphQLObjectType({
name: "UserPayload",
fields: {
user: {
type: new graphql_1.GraphQLNonNull(userType),
},
},
});
const viewerType = new graphql_1.GraphQLObjectType({
name: "Viewer",
fields: {
user: {
type: new graphql_1.GraphQLNonNull(userType),
},
},
});
const rootQuery = new graphql_1.GraphQLObjectType({
name: "RootQueryType",
fields: {
user: {
args: {
id: {
type: new graphql_1.GraphQLNonNull(graphql_1.GraphQLID),
},
},
type: userType,
resolve(_source, { id }) {
return getUser(id);
},
},
node: {
args: {
id: {
type: new graphql_1.GraphQLNonNull(graphql_1.GraphQLID),
},
},
type: graphql_2.GraphQLNodeInterface,
resolve(_source, { id }) {
return getUser(id);
},
},
},
});
const rootQueryReturnList = new graphql_1.GraphQLObjectType({
name: "RootQueryType",
fields: {
user: {
args: {
id: {
type: new graphql_1.GraphQLNonNull(graphql_1.GraphQLID),
},
},
type: new graphql_1.GraphQLNonNull(new graphql_1.GraphQLList(new graphql_1.GraphQLNonNull(userType))),
resolve(_source, { id }) {
return [getUser(id)];
},
},
node: {
args: {
id: {
type: new graphql_1.GraphQLNonNull(graphql_1.GraphQLID),
},
},
type: graphql_2.GraphQLNodeInterface,
resolve(_source, { id }) {
return getUser(id);
},
},
},
});
const viewerRootQuery = new graphql_1.GraphQLObjectType({
name: "RootQueryType",
fields: {
viewer: {
type: viewerType,
resolve() {
return {
user: getUser("20"),
};
},
},
},
});
describe("query with args", () => {
const schema = new graphql_1.GraphQLSchema({
query: rootQuery,
});
test("simple. no nulls", async () => {
const cfg = {
schema: schema,
args: {
id: "1",
},
root: "user",
};
await (0, index_1.expectQueryFromRoot)(cfg, ["id", "1"], ["firstName", "Jon"], ["lastName", "Snow"]);
});
test("with nullable root paths", async () => {
const cfg = {
schema: schema,
args: {
id: "1",
},
nullQueryPaths: ["address"],
root: "user",
};
await (0, index_1.expectQueryFromRoot)(cfg, ["id", "1"], ["address.id", null]);
});
test("with nullable sub-parts", async () => {
const cfg = {
schema: schema,
args: {
id: "2",
},
root: "user",
};
await (0, index_1.expectQueryFromRoot)(cfg, ["id", "2"], ["firstName", "Jon"], ["lastName", "Snow"], ["address.id", "23"], ["address.street", "1 main street"], ["address.state", "CA"], ["address.zipCode", "94102"], ["address.apartment", null]);
});
test("with object passed", async () => {
const cfg = {
schema: schema,
args: {
id: "2",
},
root: "user",
};
await (0, index_1.expectQueryFromRoot)(cfg, [
// TODO right now this is empty string, is there a better API for this?
"",
{
id: "2",
firstName: "Jon",
lastName: "Snow",
address: {
id: "23",
street: "1 main street",
state: "CA",
zipCode: "94102",
apartment: null,
},
},
]);
});
});
test("mutation with args", async () => {
const schema = new graphql_1.GraphQLSchema({
query: rootQuery,
mutation: new graphql_1.GraphQLObjectType({
name: "RootMutationType",
fields: {
userEdit: {
args: {
id: {
type: new graphql_1.GraphQLNonNull(graphql_1.GraphQLID),
},
firstName: {
type: graphql_1.GraphQLString,
},
lastName: {
type: graphql_1.GraphQLString,
},
},
type: userType,
resolve(_source, { id, ...args }) {
return editUser(id, args);
},
},
},
}),
});
const cfg = {
schema: schema,
args: {
id: "1",
firstName: "Aegon",
lastName: "Targaryen",
},
mutation: "userEdit",
disableInputWrapping: true,
};
// mutation query
await (0, index_1.expectMutation)(cfg, ["id", "1"], ["firstName", "Aegon"], ["lastName", "Targaryen"]);
});
test("with async callback", async () => {
const schema = new graphql_1.GraphQLSchema({
query: rootQuery,
});
const cfg = {
schema: schema,
args: {
id: "1",
},
root: "user",
};
await (0, index_1.expectQueryFromRoot)(cfg, ["id", "1"], ["firstName", "Jon"], [
"lastName",
async (arg) => {
await new Promise((resolve, reject) => {
setTimeout(() => resolve(null), 10);
});
},
]);
});
test("query with nested args", async () => {
const schema = new graphql_1.GraphQLSchema({
query: rootQuery,
});
const cfg = {
schema: schema,
args: {
id: "10",
},
root: "user",
};
await (0, index_1.expectQueryFromRoot)(cfg, ["id", "10"], ["firstName", "Jon"], ["lastName", "Snow"], ["contacts(first: 2)[0].firstName", "Robb"], ["contacts(first: 2)[0].lastName", "Stark"], ["contacts(first: 2)[0].emailAddress", "Robb@Stark.com"], ["contacts(first: 2)[1].firstName", "Sansa"], ["contacts(first: 2)[1].lastName", "Stark"], ["contacts(first: 2)[1].emailAddress", "Sansa@Stark.com"]);
});
test("query with args. extra variables", async () => {
const schema = new graphql_1.GraphQLSchema({
query: rootQuery,
});
const cfg = {
schema: schema,
args: {
id: "10",
},
extraVariables: {
domain: {
value: "Snow.com",
graphqlType: "String",
},
},
root: "user",
};
await (0, index_1.expectQueryFromRoot)(cfg, ["id", "10"], ["firstName", "Jon"], ["lastName", "Snow"], ["contacts(domain: $domain)[0].firstName", "Jon"], ["contacts(domain: $domain)[0].lastName", "Snow"], ["contacts(domain: $domain)[0].emailAddress", "Jon@Snow.com"]);
});
test("query with alias", async () => {
const schema = new graphql_1.GraphQLSchema({
query: rootQuery,
});
const cfg = {
schema: schema,
args: {
id: "10",
},
root: "user",
};
await (0, index_1.expectQueryFromRoot)(cfg, ["id", "10"], ["firstName", "Jon"], ["lastName", "Snow"], [
`contacts_stark:contacts(lastName: "Stark"){ firstName,lastName,emailAddress}`,
function (val) {
expect(val.length).toBe(5);
},
"contacts_stark",
], [
`contacts_snow:contacts(lastName: "Snow"){ firstName,lastName,emailAddress}`,
function (val) {
expect(val.length).toBe(1);
},
"contacts_snow",
]);
});
test("query with object values", async () => {
const schema = new graphql_1.GraphQLSchema({
query: rootQuery,
});
const cfg = {
schema: schema,
args: {
id: "10",
},
root: "user",
};
await (0, index_1.expectQueryFromRoot)(cfg, ["id", "10"], ["firstName", "Jon"], ["lastName", "Snow"], [
// this is better because we don't have to write complex things many times
"contacts(first: 5)",
[
{
firstName: "Robb",
lastName: "Stark",
emailAddress: "Robb@Stark.com",
phoneNumber: "415-222-3322",
},
{
firstName: "Sansa",
lastName: "Stark",
emailAddress: "Sansa@Stark.com",
phoneNumber: "415-222-3322",
},
{
firstName: "Arya",
lastName: "Stark",
emailAddress: "Arya@Stark.com",
phoneNumber: "415-222-3322",
},
{
firstName: "Bran",
lastName: "Stark",
emailAddress: "Bran@Stark.com",
phoneNumber: "415-222-3322",
},
{
firstName: "Rickon",
lastName: "Stark",
emailAddress: "Rickon@Stark.com",
phoneNumber: "415-222-3322",
},
],
], [
"address",
{
id: "23",
street: "1 main street",
state: "CA",
zipCode: "94102",
apartment: null,
},
], ["nicknames", null], ["daysOff", weekendsGQL]);
});
// top level returns list version of ^
test("list type returned with nested objects", async () => {
const schema = new graphql_1.GraphQLSchema({
query: rootQueryReturnList,
});
const cfg = {
schema: schema,
args: {
id: "10",
},
root: "user",
};
await (0, index_1.expectQueryFromRoot)(cfg, ["[0].id", "10"], ["[0].firstName", "Jon"], ["[0].lastName", "Snow"], [
// this is better because we don't have to write complex things many times
"[0].contacts(first: 5)",
[
{
firstName: "Robb",
lastName: "Stark",
emailAddress: "Robb@Stark.com",
phoneNumber: "415-222-3322",
},
{
firstName: "Sansa",
lastName: "Stark",
emailAddress: "Sansa@Stark.com",
phoneNumber: "415-222-3322",
},
{
firstName: "Arya",
lastName: "Stark",
emailAddress: "Arya@Stark.com",
phoneNumber: "415-222-3322",
},
{
firstName: "Bran",
lastName: "Stark",
emailAddress: "Bran@Stark.com",
phoneNumber: "415-222-3322",
},
{
firstName: "Rickon",
lastName: "Stark",
emailAddress: "Rickon@Stark.com",
phoneNumber: "415-222-3322",
},
],
], [
"[0].address",
{
id: "23",
street: "1 main street",
state: "CA",
zipCode: "94102",
apartment: null,
},
], ["[0].nicknames", null], ["[0].daysOff", weekendsGQL]);
});
test("mutation with nested objects", async () => {
const schema = new graphql_1.GraphQLSchema({
query: rootQuery,
mutation: new graphql_1.GraphQLObjectType({
name: "RootMutationType",
fields: {
userEdit: {
args: {
id: {
type: new graphql_1.GraphQLNonNull(graphql_1.GraphQLID),
},
firstName: {
type: graphql_1.GraphQLString,
},
lastName: {
type: graphql_1.GraphQLString,
},
},
type: new graphql_1.GraphQLNonNull(userPayloadType),
resolve(_source, { id, ...args }) {
return {
user: editUser(id, args),
};
},
},
},
}),
});
const cfg = {
schema: schema,
args: {
id: "1",
firstName: "Aegon",
lastName: "Targaryen",
},
mutation: "userEdit",
disableInputWrapping: true,
};
// mutation query
await (0, index_1.expectMutation)(cfg, ["user.id", "1"], ["user.firstName", "Aegon"], ["user.lastName", "Targaryen"], ["user.daysOff", weekendsGQL]);
});
test("query scalar list", async () => {
const schema = new graphql_1.GraphQLSchema({
query: rootQuery,
});
const cfg = {
schema: schema,
args: {
id: "1001",
},
root: "user",
};
await (0, index_1.expectQueryFromRoot)(cfg, ["id", "1001"], ["firstName", "Jon"], ["lastName", "Snow"], ["nicknames", NickNames]);
});
test("query enum list", async () => {
const schema = new graphql_1.GraphQLSchema({
query: rootQuery,
});
const cfg = {
schema: schema,
args: {
id: "1001",
},
root: "user",
};
await (0, index_1.expectQueryFromRoot)(cfg, ["id", "1001"], ["firstName", "Jon"], ["lastName", "Snow"], ["daysOff", weekendsGQL]);
});
test("nested query with object values", async () => {
const schema = new graphql_1.GraphQLSchema({
query: viewerRootQuery,
});
const cfg = {
schema: schema,
args: {},
root: "viewer",
};
await (0, index_1.expectQueryFromRoot)(cfg, ["user.id", "20"], ["user.firstName", "Jon"], ["user.lastName", "Snow"],
// TODO would be nice for this to be a partial query but not there yet
// [
// "user",
// {
// id: "20",
// firstName: "Jon",
// lastName: "Snow",
// },
// ],
[
"user.contacts(first: 5)",
[
{
firstName: "Robb",
lastName: "Stark",
emailAddress: "Robb@Stark.com",
phoneNumber: "415-222-3322",
},
{
firstName: "Sansa",
lastName: "Stark",
emailAddress: "Sansa@Stark.com",
phoneNumber: "415-222-3322",
},
{
firstName: "Arya",
lastName: "Stark",
emailAddress: "Arya@Stark.com",
phoneNumber: "415-222-3322",
},
{
firstName: "Bran",
lastName: "Stark",
emailAddress: "Bran@Stark.com",
phoneNumber: "415-222-3322",
},
{
firstName: "Rickon",
lastName: "Stark",
emailAddress: "Rickon@Stark.com",
phoneNumber: "415-222-3322",
},
],
]);
});
test("nullQueryPaths with nullable list contents", async () => {
const rootQuery = new graphql_1.GraphQLObjectType({
name: "RootQueryType",
fields: {
users: {
args: {
ids: {
type: new graphql_1.GraphQLNonNull(new graphql_1.GraphQLList(new graphql_1.GraphQLNonNull(graphql_1.GraphQLID))),
},
},
type: new graphql_1.GraphQLNonNull(new graphql_1.GraphQLList(userType)),
resolve(_source, { ids }) {
let ret = [];
for (const id of ids) {
let num = parseInt(id, 0) || 0;
if (num % 2 == 0) {
ret.push(null);
}
else {
ret.push(getUser(id));
}
}
return ret;
},
},
},
});
const schema = new graphql_1.GraphQLSchema({
query: rootQuery,
});
let cfg = {
schema: schema,
args: {
ids: ["1", "2"],
},
root: "users",
nullQueryPaths: ["[1]"],
};
await (0, index_1.expectQueryFromRoot)(cfg, ["[0].id", "1"], ["[0].firstName", "Jon"], ["[0].lastName", "Snow"], ["[1].id", null], ["[1].firstName", null], ["[1].lastName", null]);
// non-nullQuery paths way of doing it
cfg = {
schema: schema,
args: {
ids: ["1", "2"],
},
root: "users",
};
await (0, index_1.expectQueryFromRoot)(cfg, [
"",
[
{
id: "1",
firstName: "Jon",
lastName: "Snow",
},
null,
],
]);
});
test("nullQueryPaths with nullable list", async () => {
const schema = new graphql_1.GraphQLSchema({
query: rootQuery,
});
const cfg = {
schema: schema,
args: {
id: "1",
},
root: "user",
nullQueryPaths: ["contacts"],
};
await (0, index_1.expectQueryFromRoot)(cfg, ["id", "1"], ["firstName", "Jon"], ["lastName", "Snow"], ["contacts(first: 2)[0].firstName", null], ["contacts(first: 2)[0].lastName", null], ["contacts(first: 2)[0].emailAddress", null]);
});
test("undefinedQueryPaths", async () => {
const schema = new graphql_1.GraphQLSchema({
query: rootQuery,
});
const cfg = {
schema: schema,
args: {
id: "10",
},
root: "user",
undefinedQueryPaths: ["contacts"],
};
await (0, index_1.expectQueryFromRoot)(cfg, ["id", "10"], ["firstName", "Jon"], ["lastName", "Snow"], ["contacts(first: 0)[0].firstName", undefined]);
});
describe("inline fragments", () => {
const rootQuery = new graphql_1.GraphQLObjectType({
name: "RootQueryType",
fields: {
node: {
args: {
id: {
type: new graphql_1.GraphQLNonNull(graphql_1.GraphQLID),
},
},
type: graphql_2.GraphQLNodeInterface,
resolve(_source, { id }) {
return getUser(id);
},
},
},
});
const schema = new graphql_1.GraphQLSchema({
query: rootQuery,
types: [userType, contactType, addressType],
});
const cfg = {
schema: schema,
args: {
id: "10",
},
root: "node",
};
test("basic", async () => {
await (0, index_1.expectQueryFromRoot)(cfg, [
"...on User",
{
id: "10",
firstName: "Jon",
lastName: "Snow",
},
]);
});
test("list", async () => {
let cfg2 = {
...cfg,
args: {
id: "1001",
},
};
await (0, index_1.expectQueryFromRoot)(cfg2, [
"...on User",
{
id: "1001",
firstName: "Jon",
lastName: "Snow",
nicknames: NickNames,
},
]);
});
test("enum list", async () => {
const cfg2 = {
...cfg,
args: {
id: "1001",
},
};
await (0, index_1.expectQueryFromRoot)(cfg2, [
"...on User",
{
id: "1001",
firstName: "Jon",
lastName: "Snow",
daysOff: weekendsGQL,
},
]);
});
test("inline fragment root", async () => {
const cfg = {
schema: schema,
args: {
id: "10",
},
root: "node",
inlineFragmentRoot: "User",
};
await (0, index_1.expectQueryFromRoot)(cfg, ["id", "10"], ["firstName", "Jon"], ["lastName", "Snow"]);
});
test("inline fragment root with list", async () => {
const cfg = {
schema: schema,
args: {
id: "1001",
},
root: "node",
inlineFragmentRoot: "User",
};
await (0, index_1.expectQueryFromRoot)(cfg, ["id", "1001"], ["firstName", "Jon"], ["lastName", "Snow"], ["nicknames", NickNames]);
});
test("inline fragment root with enum list", async () => {
const cfg = {
schema: schema,
args: {
id: "1001",
},
root: "node",
inlineFragmentRoot: "User",
};
await (0, index_1.expectQueryFromRoot)(cfg, ["id", "1001"], ["firstName", "Jon"], ["lastName", "Snow"], ["daysOff", weekendsGQL]);
});
});
describe("file upload", () => {
async function readStream(file) {
return new Promise((resolve) => {
const stream = file.createReadStream();
let data = [];
stream.on("data", function (chunk) {
data.push(chunk.toString());
});
stream.on("close", function () {
return resolve(data.join(""));
});
});
}
const fileContents = ["col1,col2", "data1,data2"].join("\n");
const paths = ["foo.csv", "foo2.csv"];
const schema = new graphql_1.GraphQLSchema({
query: new graphql_1.GraphQLObjectType({
name: "RootQueryType",
fields: {
hello: {
type: graphql_1.GraphQLString,
resolve() {
return "world";
},
},
},
}),
mutation: new graphql_1.GraphQLObjectType({
name: "RootMutationType",
fields: {
fileUpload: {
type: new graphql_1.GraphQLNonNull(graphql_1.GraphQLBoolean),
args: {
file: {
type: new graphql_1.GraphQLNonNull(graphql_upload_1.GraphQLUpload),
},
},
async resolve(src, args) {
const file = await args.file;
const data = await readStream(file);
if (data !== fileContents) {
throw new Error(`invalid file sent`);
}
return true;
},
},
fileUploadMultiple: {
type: new graphql_1.GraphQLNonNull(graphql_1.GraphQLBoolean),
args: {
files: {
type: new graphql_1.GraphQLNonNull(new graphql_1.GraphQLList(new graphql_1.GraphQLNonNull(graphql_upload_1.GraphQLUpload))),
},
},
async resolve(src, args) {
await Promise.all(args.files.map(async (f) => {
const file = await f;
const data = await readStream(file);
if (data !== fileContents) {
throw new Error(`invalid file sent`);
}
return data;
}));
return true;
},
},
},
}),
});
beforeAll(() => {
paths.forEach((path) => fs.writeFileSync(path, fileContents, {
encoding: "utf-8",
}));
});
afterAll(() => {
paths.forEach((path) => fs.unlinkSync(path));
});
test("file path", async () => {
await (0, index_1.expectMutation)({
schema: schema,
mutation: "fileUpload",
args: {
file: "foo.csv",
},
disableInputWrapping: true,
customHandlers: [
(0, graphql_upload_1.graphqlUploadExpress)({ maxFileSize: 10000000, maxFiles: 10 }),
],
}, [".", true]);
});
test("with stream", async () => {
await (0, index_1.expectMutation)({
schema: schema,
mutation: "fileUpload",
args: {
file: fs.createReadStream("foo.csv"),
},
disableInputWrapping: true,
customHandlers: [
(0, graphql_upload_1.graphqlUploadExpress)({ maxFileSize: 10000000, maxFiles: 10 }),
],
}, [".", true]);
});
test("with buffer", async () => {
await (0, index_1.expectMutation)({
schema: schema,
mutation: "fileUpload",
args: {
file: fs.readFileSync("foo.csv"),
},
disableInputWrapping: true,
customHandlers: [
(0, graphql_upload_1.graphqlUploadExpress)({ maxFileSize: 10000000, maxFiles: 10 }),
],
}, [".", true]);
});
test("no graphqlUploadExpress", async () => {
await (0, index_1.expectMutation)({
schema: schema,
mutation: "fileUpload",
args: {
file: "foo.csv",
},
disableInputWrapping: true,
expectedStatus: 400,
// TODO not sure where this error from is but it's failing as expected which is fine
expectedError: /Must provide query string/,
}, [".", true]);
});
test("multiple files", async () => {
await (0, index_1.expectMutation)({
schema: schema,
mutation: "fileUploadMultiple",
args: {
files: paths,
},
disableInputWrapping: true,
customHandlers: [
(0, graphql_upload_1.graphqlUploadExpress)({ maxFileSize: 10000000, maxFiles: 10 }),
],
}, [".", true]);
});
});
test("false boolean", async () => {
const schema = new graphql_1.GraphQLSchema({
query: rootQuery,
mutation: new graphql_1.GraphQLObjectType({
name: "RootMutationType",
fields: {
userEdit: {
args: {
id: {
type: new graphql_1.GraphQLNonNull(graphql_1.GraphQLID),
},
firstName: {
type: graphql_1.GraphQLString,
},
lastName: {
type: graphql_1.GraphQLString,
},
log: {
type: graphql_1.GraphQLBoolean,
},
},
type: userType,
resolve(_source, { id, ...args }) {
return editUser(id, args);
},
},
},
}),
});
const cfg = {
schema: schema,
args: {
id: "1",
firstName: "Aegon",
lastName: "Targaryen",
log: false,
},
mutation: "userEdit",
disableInputWrapping: true,
};
// mutation query
await (0, index_1.expectMutation)(cfg, ["id", "1"], ["firstName", "Aegon"], ["lastName", "Targaryen"]);
});
test("custom server", async () => {
const schema = new graphql_1.GraphQLSchema({
query: new graphql_1.GraphQLObjectType({
name: "RootQueryType",
fields: {
hello: {
type: graphql_1.GraphQLString,
resolve() {
return "world";
},
},
},
}),
});
const app = (0, express_1.default)();
app.use(express_1.default.json());
app.use("/custom_graphql", async (req, res) => {
const { operationName, query, variables } = (0, graphql_helix_1.getGraphQLParameters)(req);
const result = await (0, graphql_helix_1.processRequest)({
operationName,
query,
variables,
request: req,
schema,
contextFactory: async () => {
return (0, auth_1.buildContext)(req, res);
},
});
await (0, graphql_helix_1.sendResult)(result, res);
});
app.use("/hello", async (req, res) => res.json({ world: true }));
const r = await (0, supertest_1.default)(app).get("/hello").send();
expect(r.error).toBe(false);
expect(r.body).toStrictEqual({ world: true });
await (0, index_1.expectQueryFromRoot)({
schema,
server: app,
graphQLPath: "/custom_graphql",
args: {},
root: "hello",
}, ["", "world"]);
// content type error because we tried to hit /graphql even though doesn't exist
expect((0, index_1.expectQueryFromRoot)({
schema,
server: app,
args: {},
root: "hello",
}, ["", "world"])).rejects.toThrow('"Content-Type" matching /json/');
});