Skip to content

Commit

Permalink
tests
Browse files Browse the repository at this point in the history
  • Loading branch information
iartemiev committed Oct 15, 2024
1 parent c17e6f8 commit 300ec26
Show file tree
Hide file tree
Showing 6 changed files with 213 additions and 105 deletions.
16 changes: 8 additions & 8 deletions .github/integ-config/integ-all.yml
Original file line number Diff line number Diff line change
Expand Up @@ -701,14 +701,14 @@ tests:
browser: *minimal_browser_list

# GEO
# - test_name: integ_react_geo_display_map
# desc: 'Display Map'
# framework: react
# category: geo
# sample_name: [display-map]
# spec: display-map
# # Temp fix:
# browser: [chrome]
- test_name: integ_react_geo_display_map
desc: 'Display Map'
framework: react
category: geo
sample_name: [display-map]
spec: display-map
# Temp fix:
browser: [chrome]
- test_name: integ_react_geo_search_outside_map
desc: 'Search Outside Map'
framework: react
Expand Down
2 changes: 1 addition & 1 deletion .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
"--inspect-brk",
"${workspaceRoot}/node_modules/.bin/jest",
// Optionally specify a single test file to run/debug:
"AWSAppSyncRealTimeProvider.test.ts",
"generateClient.test.ts",
"--runInBand",
"--testTimeout",
"600000", // 10 min timeout so jest doesn't error while we're stepping through code
Expand Down
242 changes: 188 additions & 54 deletions packages/api-graphql/__tests__/events.test.ts
Original file line number Diff line number Diff line change
@@ -1,78 +1,212 @@
import { Subscription } from 'rxjs';
import { Amplify } from '@aws-amplify/core';
import { MESSAGE_TYPES } from '../src/Providers/constants';
import * as constants from '../src/Providers/constants';

import {
delay,
FakeWebSocketInterface,
replaceConstant,
} from '../__tests__/helpers';
import { ConnectionState as CS } from '../src/types/PubSub';

import { AWSAppSyncEventProvider } from '../src/Providers/AWSAppSyncEventsProvider';
import { AppSyncEventProvider } from '../src/Providers/AWSAppSyncEventsProvider';

import { events } from '../src/';
import { appsyncRequest } from '../src/internals/events/appsyncRequest';
import { GraphQLAuthMode } from '@aws-amplify/core/internals/utils';

const abortController = new AbortController();

var mockSubscribeObservable: any;

jest.mock('../src/Providers/AWSAppSyncEventsProvider', () => {
mockSubscribeObservable = jest.fn(() => ({
subscribe: jest.fn(),
}));

return {
AppSyncEventProvider: {
connect: jest.fn(),
subscribe: jest.fn(mockSubscribeObservable),
publish: jest.fn(),
close: jest.fn(),
},
};
});

jest.mock('../src/internals/events/appsyncRequest', () => {
return {
appsyncRequest: jest.fn().mockResolvedValue({}),
};
});

/**
* TODO:
* 1. gen2 config
* 2. manual config
* 3. all auth modes
* 4. ensure auth works as expected for all modes/locations
* Note: thorough auth testing, including validating correct auth header generation
* is performed in __tests__/AWSAppSyncRealTimeProvider.test.ts
*
* The auth implementation is shared between AWSAppSyncEventsProvider and AWSAppSyncRealTimeProvider,
* so we're just sanity checking that the expected auth mode is passed to the provider in this test file.
*/

test('no configure()', async () => {
await expect(events.connect('/')).rejects.toThrow(
'Amplify configuration is missing. Have you called Amplify.configure()?',
);
});
describe('Events', () => {
afterAll(() => {
jest.resetAllMocks();
jest.clearAllMocks();
});

describe('config', () => {
test('no configure()', async () => {
await expect(events.connect('/')).rejects.toThrow(
'Amplify configuration is missing. Have you called Amplify.configure()?',
);
});

describe('Events Client', () => {
beforeEach(() => {
Amplify.configure({
custom: {
events: {
url: 'https://not-a-real.ddpg-api.us-west-2.amazonaws.com/event',
aws_region: 'us-west-2',
default_authorization_type: 'API_KEY',
api_key: 'da2-abcxyz321',
test('manual (resource config)', async () => {
Amplify.configure({
API: {
Events: {
endpoint:
'https://not-a-real.ddpg-api.us-west-2.amazonaws.com/event',
region: 'us-west-2',
defaultAuthMode: 'apiKey',
apiKey: 'da2-abcxyz321',
},
},
},
version: '1.2',
});

await expect(events.connect('/')).resolves.not.toThrow();
});

test('outputs (amplify-backend config)', async () => {
Amplify.configure({
custom: {
events: {
url: 'https://not-a-real.ddpg-api.us-west-2.amazonaws.com/event',
aws_region: 'us-west-2',
default_authorization_type: 'API_KEY',
api_key: 'da2-abcxyz321',
},
},
version: '1.2',
});

await expect(events.connect('/')).resolves.not.toThrow();
});
});

const authModes: GraphQLAuthMode[] = [
'apiKey',
'userPool',
'oidc',
'iam',
'lambda',
'none',
];

describe('channel', () => {
test('happy connect', async () => {
const channel = await events.connect('/');

expect(channel.subscribe).toBeInstanceOf(Function);
expect(channel.close).toBeInstanceOf(Function);
describe('client', () => {
beforeEach(() => {
Amplify.configure({
API: {
Events: {
endpoint:
'https://not-a-real.ddpg-api.us-west-2.amazonaws.com/event',
region: 'us-west-2',
defaultAuthMode: 'apiKey',
apiKey: 'da2-abcxyz321',
},
},
});
});

describe('auth modes', () => {
let provider: typeof AWSAppSyncEventProvider;
let providerSpy: any;
const authModes: GraphQLAuthMode[] = [
'apiKey',
'userPool',
'oidc',
'iam',
'lambda',
'none',
];

describe('channel', () => {
test('happy connect', async () => {
const channel = await events.connect('/');

expect(channel.subscribe).toBeInstanceOf(Function);
expect(channel.close).toBeInstanceOf(Function);
});

describe('auth modes', () => {
let mockProvider: typeof AppSyncEventProvider;

beforeEach(() => {
mockProvider = AppSyncEventProvider;
});

for (const authMode of authModes) {
test(`auth override: ${authMode}`, async () => {
await events.connect('/', { authMode });

expect(mockProvider.connect).toHaveBeenCalledWith(
expect.objectContaining({ authenticationType: authMode }),
);
});
}
});
});

describe('subscribe', () => {
test('happy subscribe', async () => {
const channel = await events.connect('/');

channel.subscribe({
next: data => void data,
error: error => void error,
});
});

describe('auth modes', () => {
let mockProvider: typeof AppSyncEventProvider;

beforeEach(() => {
mockProvider = AppSyncEventProvider;
});

for (const authMode of authModes) {
test(`auth override: ${authMode}`, async () => {
const channel = await events.connect('/');

channel.subscribe(
{
next: data => void data,
error: error => void error,
},
{ authMode },
);

expect(mockSubscribeObservable).toHaveBeenCalledWith(
expect.objectContaining({ authenticationType: authMode }),
);
});
}
});
});

describe('post', () => {
let mockReq: typeof appsyncRequest;

beforeEach(() => {
provider = new AWSAppSyncEventProvider();
providerSpy = jest.spyOn(provider, 'connect');
mockReq = appsyncRequest;
});

test('happy post', async () => {
await events.post('/', { test: 'data' });

expect(mockReq).toHaveBeenCalledWith(
Amplify,
expect.objectContaining({
query: '/',
variables: ['{"test":"data"}'],
}),
{},
abortController,
);
});

for (const authMode of authModes) {
test(`auth override: ${authMode}`, async () => {
await events.connect('/', { authMode });
await events.post('/', { test: 'data' }, { authMode });

expect(mockReq).toHaveBeenCalledWith(
Amplify,
expect.objectContaining({
query: '/',
variables: ['{"test":"data"}'],
authenticationType: authMode,
}),
{},
abortController,
);
});
}
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { CustomHeaders } from '@aws-amplify/data-schema/runtime';
import { MESSAGE_TYPES } from '../constants';
import { AWSWebSocketProvider } from '../AWSWebSocketProvider';
import { awsRealTimeHeaderBasedAuth } from '../AWSWebSocketProvider/authHeaders';

// resolved/actual AuthMode values. identityPool gets resolves to IAM upstream in InternalGraphQLAPI._graphqlSubscribe
type ResolvedGraphQLAuthModes = Exclude<GraphQLAuthMode, 'identityPool'>;

Expand Down Expand Up @@ -42,7 +43,7 @@ interface DataResponse {

const PROVIDER_NAME = 'AWSAppSyncEventsProvider';

export class AWSAppSyncEventProvider extends AWSWebSocketProvider {
class AWSAppSyncEventProvider extends AWSWebSocketProvider {
constructor() {
super(PROVIDER_NAME);
}
Expand Down Expand Up @@ -182,3 +183,5 @@ export class AWSAppSyncEventProvider extends AWSWebSocketProvider {
};
}
}

export const AppSyncEventProvider = new AWSAppSyncEventProvider();
6 changes: 1 addition & 5 deletions packages/api-graphql/src/internals/events/appsyncRequest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,7 @@ import {
GraphQLAuthMode,
getAmplifyUserAgent,
} from '@aws-amplify/core/internals/utils';
import {
// cancel as cancelREST,
post,
// updateRequestToBeCancellable,
} from '@aws-amplify/api-rest/internals';
import { post } from '@aws-amplify/api-rest/internals';
import {
CustomHeaders,
RequestOptions,
Expand Down
Loading

0 comments on commit 300ec26

Please sign in to comment.