Files
alighasami 3d5eaf9445
Security: Sync from Public / sync-from-public (push) Has been cancelled
Test: Benchmark Nightly / build (push) Has been cancelled
Test: Benchmark Nightly / Notify Cats on failure (push) Has been cancelled
CI: Python / Checks (push) Has been cancelled
Test: Evals Python / Workflow Comparison Python (push) Has been cancelled
Util: Check Docs URLs / check-docs-urls (push) Has been cancelled
Test: Visual Storybook / Cloudflare Pages (push) Has been cancelled
Test: E2E Performance / build-and-test-performance (push) Has been cancelled
Test: Workflows Nightly / Run Workflow Tests (push) Has been cancelled
Util: Cleanup CI Docker Images / Delete stale CI images (push) Has been cancelled
Test: Benchmark Destroy Env / build (push) Has been cancelled
Util: Update Node Popularity / update-popularity (push) Has been cancelled
Test: E2E Coverage Weekly / Coverage Tests (push) Has been cancelled
first commit
2026-03-17 16:22:57 +03:30

97 lines
3.2 KiB
TypeScript

import { CredentialsHelper } from '@nodes-testing/credentials-helper';
import { NodeTestHarness } from '@nodes-testing/node-test-harness';
import nock from 'nock';
import { credentials } from '../credentials';
describe('Microsoft SharePoint Node - Token Refresh', () => {
const { baseUrl } = credentials.microsoftSharePointOAuth2Api;
const tokenRefreshUrl = 'https://login.microsoftonline.com';
const itemPath =
'/sites/site1/lists/list1/items/item1?%24select=id%2CcreatedDateTime%2ClastModifiedDateTime%2CwebUrl&%24expand=fields%28select%3DTitle%29';
let updateCredentialsSpy: jest.SpyInstance;
beforeAll(() => {
// Mock the credential helper to return oAuth2Api as parent type
jest.spyOn(CredentialsHelper.prototype, 'getParentTypes').mockReturnValue(['oAuth2Api']);
});
beforeEach(() => {
// Spy on the updateCredentialsOauthTokenData to verify token refresh
updateCredentialsSpy = jest
.spyOn(CredentialsHelper.prototype, 'updateCredentialsOauthTokenData')
.mockResolvedValue();
// Set up mocks for token refresh scenario
// First request: Return 401 Unauthorized (expired token)
nock(baseUrl)
.get(itemPath)
.matchHeader('Authorization', 'Bearer ACCESSTOKEN')
.reply(401, {
error: {
code: 'InvalidAuthenticationToken',
message: 'Access token has expired.',
},
});
// Token refresh request
nock(tokenRefreshUrl).post('/common/oauth2/v2.0/token').reply(200, {
token_type: 'Bearer',
scope:
'https://mydomain.sharepoint.com/Sites.Manage.All https://mydomain.sharepoint.com/.default',
expires_in: 3599,
ext_expires_in: 3599,
access_token: 'NEWACCESSTOKEN',
refresh_token: 'NEWREFRESHTOKEN',
});
// Retry request with new token: Return success
nock(baseUrl)
.get(itemPath)
.matchHeader('Authorization', 'Bearer NEWACCESSTOKEN')
.reply(200, {
'@odata.context':
'https://mydomain.sharepoint.com/sites/site1/_api/v2.0/$metadata#listItems/$entity',
'@odata.etag': '"07bfcdd5-450d-48ce-8dc3-04f7f59edc5f,1"',
id: 'item1',
createdDateTime: '2025-03-12T22:18:18Z',
lastModifiedDateTime: '2025-03-12T22:18:18Z',
webUrl: 'https://mydomain.sharepoint.com/sites/site1/Lists/name%20list/1_.000',
'fields@odata.navigationLink': 'sites/site1/lists/list1/items/item1/fields',
fields: {
'@odata.etag': '"07bfcdd5-450d-48ce-8dc3-04f7f59edc5f,1"',
Title: 'Item 1',
},
});
});
afterEach(() => {
nock.cleanAll();
});
afterAll(() => {
jest.restoreAllMocks();
});
// Use the harness's setupTests to automatically run the workflow
new NodeTestHarness().setupTests({
credentials,
workflowFiles: ['getTokenRefresh.workflow.json'],
customAssertions: () => {
// Verify the token was refreshed and saved
expect(updateCredentialsSpy).toHaveBeenCalledTimes(1);
expect(updateCredentialsSpy.mock.calls[0][1]).toBe('microsoftSharePointOAuth2Api');
expect(updateCredentialsSpy.mock.calls[0][2]).toMatchObject({
oauthTokenData: expect.objectContaining({
access_token: 'NEWACCESSTOKEN',
refresh_token: 'NEWREFRESHTOKEN',
}),
});
// Verify all nock interceptors were called (401 -> refresh -> retry)
expect(nock.isDone()).toBe(true);
},
});
});