Skip to content

Commit

Permalink
Attempt to support both jsdom and node tests.
Browse files Browse the repository at this point in the history
  • Loading branch information
Konard committed Oct 21, 2023
1 parent 6bc4ffa commit 033dcf3
Show file tree
Hide file tree
Showing 4 changed files with 276 additions and 211 deletions.
16 changes: 14 additions & 2 deletions jest.config.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,16 @@
export default {
testEnvironment: 'node',
verbose: true,
};

projects: [
{
displayName: 'dom',
testEnvironment: 'jsdom',
testMatch: [ '**/?(*.)+(react.test).[jt]s?(x)' ]
},
{
displayName: 'node',
testEnvironment: 'node',
testMatch: [ '**/?(*.)+(integration|unit).test.[jt]s?(x)' ],
},
],
};
9 changes: 9 additions & 0 deletions react.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { createRequire } from 'module';
import { jest } from '@jest/globals';
const require = createRequire(import.meta.url);

require('dotenv').config();

jest.setTimeout(120000);

import './tests/client.react'
253 changes: 253 additions & 0 deletions tests/client.react.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,253 @@
import { generateApolloClient } from '@deep-foundation/hasura/client.js';
import { DeepClient, SerialOperation, useDeepSubscription } from "../imports/client";
import { assert } from 'chai';
import { BoolExpLink, MutationInputLink } from "../imports/client_types";
import { inspect } from 'util'
import { createSerialOperation } from "../imports/gql";
import { render, screen, waitFor } from '@testing-library/react'
import { DeepProvider } from '../imports/client';
import React, { useEffect } from "react";
import { ApolloClient, ApolloProvider } from '@apollo/client/index.js';
import '@testing-library/jest-dom';
import { useDeep } from '../imports/client';
import { IApolloClientGeneratorOptions } from '@deep-foundation/hasura/client';
import { ApolloClientTokenizedProvider } from '@deep-foundation/react-hasura/apollo-client-tokenized-provider'
import { TokenProvider } from '../imports/react-token';
import { LocalStoreProvider } from '@deep-foundation/store/local';
import { QueryStoreProvider } from '@deep-foundation/store/query';
import { CookiesStoreProvider } from '@deep-foundation/store/cookies';
import { CapacitorStoreProvider } from "@deep-foundation/store/capacitor";

function Main({ options }: { options: IApolloClientGeneratorOptions }): JSX.Element {
return <ApolloClientTokenizedProvider options={options}>
<div></div>
</ApolloClientTokenizedProvider>
}

const graphQlPath = `${process.env.DEEPLINKS_HASURA_PATH}/v1/graphql`;
const ssl = !!+process.env.DEEPLINKS_HASURA_SSL;
const secret = process.env.DEEPLINKS_HASURA_SECRET;
const ws = true;

let apolloClient: ApolloClient<any>;
let deepClient: DeepClient;

beforeAll(async () => {
apolloClient = generateApolloClient({
path: graphQlPath,
ssl,
secret,
ws
});
deepClient = new DeepClient({ apolloClient });
})

describe('client-react', () => {
describe(`useDeepSubscription`, () => {
it(`type`, async () => {
await setup();

expect(screen.getByText('Loading...')).toBeInTheDocument();

await waitFor(() => {
expect(screen.queryByText('Loading...')).not.toBeInTheDocument();
});

expect(screen.queryByText(/^Error:/)).not.toBeInTheDocument();

await waitFor(() => {
const dataLengthText = screen.getByText(/items loaded$/);
expect(dataLengthText).toBeInTheDocument();
const dataLength = parseInt(dataLengthText.textContent);
expect(dataLength).toBeGreaterThan(0);
}, { timeout: 10000 });



async function setup() {
const typeTypeLinkId = await deepClient.id("@deep-foundation/core", "Type");

function TestHookComponent() {
const { loading, data, error } = useDeepSubscription({
type_id: typeTypeLinkId,
});
if (loading) {
return <div>Loading...</div>;
}

if (error) {
return <div>Error: {error.message}</div>
}

return <div>{data.length} items loaded</div>;
}

render(
<ApolloProvider client={deepClient.apolloClient}>
<DeepProvider>
<TestHookComponent />
</DeepProvider>
</ApolloProvider>
);
}
})
it('rerender with loading:true must occur only once', async () => {
let renderCount = 0;
let loadingCount = 0;

function TestComponent() {
const deepSubscriptionResult = useDeepSubscription({
id: {
_id: ['@deep-foundation/core']
}
});

renderCount += 1;

if (deepSubscriptionResult.loading) {
loadingCount += 1;
}

return null;
}

render(
<ApolloProvider client={deepClient.apolloClient}>
<DeepProvider>
<TestComponent />
</DeepProvider>
</ApolloProvider>
);

await waitFor(() => {
assert(renderCount > 1, 'TestComponent must be rerendered more than once');
assert(loadingCount === 1, 'loading:true must occur only once');
});
});
it('rerender with loading:false must occur only once', async () => {
let renderCount = 0;
let loadingCount = 0;

function TestComponent() {
const deepSubscriptionResult = useDeepSubscription({
id: {
_id: ['@deep-foundation/core']
}
});

renderCount += 1;

if (!deepSubscriptionResult.loading) {
loadingCount += 1;
}

return null;
}

render(
<ApolloProvider client={deepClient.apolloClient}>
<DeepProvider>
<TestComponent />
</DeepProvider>
</ApolloProvider>
);

await waitFor(() => {
assert(renderCount > 1, 'TestComponent must be rerendered more than once');
assert(loadingCount === 1, 'loading:false must occur only once');
});
});
})
describe('login', () => {
it('login with token', async () => {
const apolloClient = generateApolloClient({
path: graphQlPath,
ssl: ssl,
});
const unloginedDeep = new DeepClient({ apolloClient });
const guest = await unloginedDeep.guest();
const guestDeep = new DeepClient({ deep: unloginedDeep, ...guest });
const admin = await guestDeep.login({
linkId: await guestDeep.id('deep', 'admin'),
});
const adminToken = admin.token;
const deep = new DeepClient({ deep: guestDeep, ...admin });
let deepInComponent: DeepClient;

function DeepConsumerComponent() {
deepInComponent = useDeep();

return null;
}

render(
<CapacitorStoreProvider>
<QueryStoreProvider>
<CookiesStoreProvider>
<LocalStoreProvider>
<TokenProvider>
<ApolloClientTokenizedProvider
options={{
client: "@deep-foundation/sdk",
token: adminToken,
path: graphQlPath,
ws: true,
}}
>
<DeepProvider>
<DeepConsumerComponent />
</DeepProvider>
</ApolloClientTokenizedProvider>
</TokenProvider>
</LocalStoreProvider>
</CookiesStoreProvider>
</QueryStoreProvider>
</CapacitorStoreProvider>
);

await waitFor(() => {
assert(deepInComponent.linkId !== 0, 'deep.linkId is 0. Failed to login');
});
})
it('login with token in apollo client', async () => {
// await deepClient.whoami(); // ApolloError: Int cannot represent non-integer value: NaN
const unloginedDeep = new DeepClient({ apolloClient });
const guest = await unloginedDeep.guest();
const guestDeep = new DeepClient({ deep: unloginedDeep, ...guest });
const admin = await guestDeep.login({
linkId: await guestDeep.id('deep', 'admin'),
});
const deepClient = new DeepClient({ deep: guestDeep, ...admin });
assert.isTrue(!!deepClient.token)
let deepInComponent: DeepClient;

function TestComponent() {
deepInComponent = useDeep();

return null;
}

render(
<QueryStoreProvider>
<LocalStoreProvider>
<ApolloClientTokenizedProvider options={{
path: graphQlPath,
ssl: ssl,
token: deepClient.token
}}>
<TokenProvider>
<DeepProvider>
<TestComponent />
</DeepProvider>
</TokenProvider>
</ApolloClientTokenizedProvider>
</LocalStoreProvider>
</QueryStoreProvider>
);

await waitFor(() => {
assert(deepInComponent.linkId !== 0, 'deep.linkId is 0. Failed to login');
});
})
})
});
Loading

0 comments on commit 033dcf3

Please sign in to comment.