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 0619318
Show file tree
Hide file tree
Showing 12 changed files with 261 additions and 145 deletions.
44 changes: 22 additions & 22 deletions .github/integ-config/detox-integ-all.yml
Original file line number Diff line number Diff line change
@@ -1,22 +1,22 @@
# - test_name: 'integ_rn_ios_storage'
# working_directory: amplify-js-samples-staging/samples/react-native/storage/StorageApp
# timeout_minutes: 120
# - test_name: 'integ_rn_ios_storage_multipart_progress'
# working_directory: amplify-js-samples-staging/samples/react-native/storage/MultiPartUploadWithProgress
# timeout_minutes: 120
# - test_name: 'integ_rn_ios_device_tracking'
# working_directory: amplify-js-samples-staging/samples/react-native/auth/deviceTracking
# timeout_minutes: 120
# - test_name: 'integ_rn_ios_datastore_sqlite_adapter'
# working_directory: amplify-js-samples-staging/samples/react-native/datastore/SQLiteAdapter
# timeout_minutes: 120
# - test_name: 'integ_rn_ios_api_gen2_rn_72_detox_cli'
# working_directory: amplify-js-samples-staging/samples/react-native/api/gen2/ApiGraphQLGen2
# timeout_minutes: 120
# - test_name: 'integ_rn_ios_api_v6_rn_72_detox_cli'
# working_directory: amplify-js-samples-staging/samples/react-native/api/v6/ApiGRAPHQL
# timeout_minutes: 120
# - test_name: 'integ_rn_ios_oidc_signout'
# working_directory: amplify-js-samples-staging/samples/react-native/auth/HosteduiApp
# timeout_minutes: 120
# host_signout_page: true
- test_name: 'integ_rn_ios_storage'
working_directory: amplify-js-samples-staging/samples/react-native/storage/StorageApp
timeout_minutes: 120
- test_name: 'integ_rn_ios_storage_multipart_progress'
working_directory: amplify-js-samples-staging/samples/react-native/storage/MultiPartUploadWithProgress
timeout_minutes: 120
- test_name: 'integ_rn_ios_device_tracking'
working_directory: amplify-js-samples-staging/samples/react-native/auth/deviceTracking
timeout_minutes: 120
- test_name: 'integ_rn_ios_datastore_sqlite_adapter'
working_directory: amplify-js-samples-staging/samples/react-native/datastore/SQLiteAdapter
timeout_minutes: 120
- test_name: 'integ_rn_ios_api_gen2_rn_72_detox_cli'
working_directory: amplify-js-samples-staging/samples/react-native/api/gen2/ApiGraphQLGen2
timeout_minutes: 120
- test_name: 'integ_rn_ios_api_v6_rn_72_detox_cli'
working_directory: amplify-js-samples-staging/samples/react-native/api/v6/ApiGRAPHQL
timeout_minutes: 120
- test_name: 'integ_rn_ios_oidc_signout'
working_directory: amplify-js-samples-staging/samples/react-native/auth/HosteduiApp
timeout_minutes: 120
host_signout_page: true
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
28 changes: 14 additions & 14 deletions .github/workflows/callable-e2e-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -61,17 +61,17 @@ jobs:
# timeout_minutes: ${{ matrix.integ-config.timeout_minutes || 35 }}
# retry_count: ${{ matrix.integ-config.retry_count || 3 }}

# detox-e2e-test-runner:
# name: E2E test runner
# needs: e2e-prep
# strategy:
# matrix:
# integ-config: ${{ fromJson(needs.e2e-prep.outputs.detox-integ-config) }}
# fail-fast: false
# secrets: inherit
# uses: ./.github/workflows/callable-e2e-test-detox.yml
# with:
# test_name: ${{ matrix.integ-config.test_name }}
# working_directory: ${{ matrix.integ-config.working_directory }}
# timeout_minutes: ${{ matrix.integ-config.timeout_minutes || 45 }}
# host_signout_page: ${{ matrix.integ-config.host_signout_page || false }}
detox-e2e-test-runner:
name: E2E test runner
needs: e2e-prep
strategy:
matrix:
integ-config: ${{ fromJson(needs.e2e-prep.outputs.detox-integ-config) }}
fail-fast: false
secrets: inherit
uses: ./.github/workflows/callable-e2e-test-detox.yml
with:
test_name: ${{ matrix.integ-config.test_name }}
working_directory: ${{ matrix.integ-config.working_directory }}
timeout_minutes: ${{ matrix.integ-config.timeout_minutes || 45 }}
host_signout_page: ${{ matrix.integ-config.host_signout_page || false }}
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
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ jest.mock('@aws-amplify/core/internals/aws-client-utils', () => {
);
return {
...original,
signRequest: (_request, _options) => {
signRequest: (_request: any, _options: any) => {
return {
method: 'test',
headers: { test: 'test' },
Expand All @@ -47,7 +47,7 @@ jest.mock('@aws-amplify/core', () => {
};
return {
...original,
fetchAuthSession: (_request, _options) => {
fetchAuthSession: (_request: any, _options: any) => {
return Promise.resolve(session);
},
Amplify: {
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
Loading

0 comments on commit 0619318

Please sign in to comment.