UNPKG

cumulocity-cypress

Version:
156 lines (155 loc) 6.55 kB
import { FetchClient, } from "@c8y/client"; import { getCookieValue, toWindowFetchResponse, wrapFetchResponse, } from "../../shared/c8yclient"; import { isAuthOptions } from "../../shared/auth"; import { getAuthOptions, getBaseUrlFromEnv, getC8yClientAuthentication, } from "../utils"; import { get_i } from "../../shared/util"; const { _ } = Cypress; export class C8yPactFetchClient extends FetchClient { constructor(options) { const auth = getC8yClientAuthentication(options.auth); const url = options.baseUrl || getBaseUrlFromEnv(); let authOptions; if (_.isString(auth)) { authOptions = getAuthOptions(auth); } else if (isAuthOptions(auth)) { authOptions = auth; } if (!url) { throw new Error("C8yPactFetchClient Error. No baseUrl provided."); } const [user, userAlias] = [ // @ts-expect-error authOptions?.user || auth?.user || Cypress.env("C8Y_LOGGED_IN_USER"), authOptions?.userAlias || Cypress.env("C8Y_LOGGED_IN_USER_ALIAS"), ]; super(auth, url); this.authOptions = authOptions; this.authentication = auth; this.cypresspact = options?.cypresspact; this.user = user; this.userAlias = userAlias; } getUser() { return [this.user, this.userAlias]; } async fetch(url, fetchOptions) { const setUserEnv = () => { Cypress.env("C8Y_LOGGED_IN_USER_ALIAS", this.userAlias); Cypress.env("C8Y_LOGGED_IN_USER", this.user); }; const isRecordingEnabled = this.cypresspact?.isRecordingEnabled() === true; const isMockingEnabled = this.cypresspact?.isMockingEnabled() === true; const currentPact = this.cypresspact?.current; if (!isRecordingEnabled && isMockingEnabled) { const fullUrl = this.getUrl(url, fetchOptions); const relativeUrl = fullUrl.replace(this.baseUrl || "", ""); let strictMocking = this.cypresspact?.getConfigValue("strictMocking") === true; const consoleProps = { pact: currentPact, url: fullUrl, relativeUrl, strictMocking, fetchOptions, baseUrl: this.baseUrl, authentication: this.authentication, }; let logger = undefined; if (this.cypresspact?.debugLog === true) { logger = Cypress.log({ autoEnd: false, name: "c8ypact", message: `mock ${relativeUrl || null}`, consoleProps: () => consoleProps, }); } if (currentPact) { let record = currentPact.nextRecordMatchingRequest({ url: fullUrl?.replace(this.baseUrl || "", ""), method: fetchOptions?.method, }); consoleProps.record = record; if (record) { if (_.isFunction(this.cypresspact?.on.mockRecord)) { record = this.cypresspact?.on.mockRecord(record) || null; consoleProps.record = record; } if (record) { const response = toWindowFetchResponse(record); consoleProps.mockedResponse = response || null; if (response) { logger?.end(); return Promise.resolve(response); } } else { strictMocking = false; } } } logger?.end(); if (strictMocking) { const error = new Error(`Mocking failed in C8yPactFetchClient. No recording found for request "${relativeUrl}". Do re-recording or disable Cypress.c8ypact.config.strictMocking.`); error.name = "C8yPactError"; throw error; } else if (this.authentication == null) { const error = new Error(`Mocking failed in C8yPactFetchClient. No recording found for request "${relativeUrl}". If strictMocking is disabled, authentication is required.`); error.name = "C8yPactError"; throw error; } } try { const response = await super.fetch(url, fetchOptions); if (this.cypresspact == null || !isRecordingEnabled) { return Promise.resolve(response); } const result = await this.savePact(response, url, fetchOptions); return Promise.resolve(result); } catch (failure) { if (this.cypresspact == null || !isRecordingEnabled) { setUserEnv(); return Promise.reject(failure); } const result = await this.savePact(failure, url, fetchOptions); return Promise.reject(result); } } getFetchOptions(options) { const result = super.getFetchOptions(options); // for full authentication xsrf token and bearer token are required // always add Bearer token if no authorization header is set if (!get_i(result, "headers.Authorization")) { const bearer = this.authOptions?.bearer || getCookieValue("Authorization"); if (bearer) { // xsrf token header is set in CookieAuth result.headers = Object.assign({ Authorization: `Bearer ${bearer}` }, result.headers); } } return result; } async savePact(response, url, fetchOptions) { let result = response; let responseObj = response.responseObj; if (!response.responseObj) { const fullUrl = this.getUrl(url, fetchOptions); result = await wrapFetchResponse(response, { url: new URL(fullUrl, this.baseUrl), fetchOptions: this.getFetchOptions(fetchOptions), }); responseObj = result.responseObj; } else { delete response.responseObj; } await this.cypresspact?.savePact(responseObj, { _auth: this.authentication, }, { noqueue: true, loggedInUser: this.user, loggedInUserAlias: this.userAlias, }); return result; } }