UNPKG

@kwiz/common

Version:

KWIZ common utilities and helpers for M365 platform

182 lines (157 loc) 6.12 kB
import { getToken } from "./auth"; import "dotenv/config"; import XMLHttpRequest from "xhr2" import * as rest from '../src/utils/rest'; import { GetSiteId } from '../src/utils/sharepoint.rest/web'; import { IRequestBody, IRestOptions } from "../src"; import { JSDOM } from 'jsdom'; import assert from "assert"; declare module "mocha" { interface Context { token: string; siteUrl: string; siteId: string; deleteTempSite: boolean; } } async function beforeAll() { this.token = await getToken(); assert(this.token, "must get token"); patchXHR(); patchGetJson(this.token); patchDOM(); if (!process.env.tempSiteOwner && process.env.tempSiteUrl) { // use the given site url and do not delete it after tests patchWindow(process.env.tempSiteUrl); this.siteUrl = process.env.tempSiteUrl; this.siteId = await GetSiteId(this.siteUrl); this.deleteTempSite = false; console.log(`Using existing site: ${this.siteUrl}\n`); } else if (process.env.tempSiteOwner && !process.env.tempSiteUrl) { // create a new site and delete it after tests const tempSite = await createTempSite(this.token); this.siteUrl = tempSite.SiteUrl; this.siteId = tempSite.SiteId; this.deleteTempSite = true; patchWindow(this.siteUrl); console.log(`Created temporary site: ${this.siteUrl}\n`); } else { assert.fail("Either tempSiteOwner or tempSiteUrl env variables must be set, but not both."); } assert(this.siteUrl, "must get siteUrl"); assert(this.siteId, "must get siteId"); assert(this.deleteTempSite !== undefined, "must set deleteTempSite"); } async function afterAll() { if (this.deleteTempSite === true) { await deleteTempSite(this.token, this.siteId); console.log(`Deleted temporary site: ${this.siteUrl}`); } } async function createTempSite(token: string) { const date = new Date().toISOString(); const dateUriSafe = date.replace(/:/g, "-") const request = { Title: `kwiz/common [integration tests] [${date}]`, Url: `https://${process.env.tenantName}.sharepoint.com/sites/kwiz_common_integration_tests_${dateUriSafe}`, Description: "Generated as a sandbox while running @kwiz/common integration tests.", WebTemplate: "SITEPAGEPUBLISHING#0", // communication site SiteDesignId: "f6cc5403-0d63-442e-96c0-285923709ffc", // blank Owner: process.env.tempSiteOwner, }; const response = await fetch( `https://${process.env.tenantName}.sharepoint.com/_api/SPSiteManager/create`, { method: 'POST', body: JSON.stringify({ request }), headers: { Authorization: `Bearer ${token}`, "Content-Type": "application/json;odata.metadata=none", "OData-Version": "4.0", } } ); if (!response.ok) { throw new Error(`fetch error: ${response.status}`); } const payload = await response.json(); if (payload.SiteStatus !== 2) { throw new Error(`_api/SPSiteManager/create error: ${payload.SiteStatus}`); } return payload; } async function deleteTempSite(token: string, siteId: string) { const response = await fetch( `https://${process.env.tenantName}.sharepoint.com/_api/SPSiteManager/delete`, { method: 'POST', body: JSON.stringify({ siteId }), headers: { Authorization: `Bearer ${token}`, "Content-Type": "application/json;odata.metadata=none", "OData-Version": "4.0", } } ); if (!response.ok) { throw new Error(`fetch error: ${response.status}`); } } function patchWindow(url: string) { const u = new URL(url); (global as any).window = { location: { protocol: u.protocol, // "https:" hostname: u.hostname, // "{tenantName}.sharepoint.com" host: u.host, // "{tenantName}.sharepoint.com" origin: u.origin, // "https://{tenantName}.sharepoint.com" pathname: u.pathname, // "/sites/kwiz_common_integration_tests_..." href: u.href, // "https://{tenantName}.sharepoint.com/sites/kwiz_common_integration_tests_..." }, }; } function patchDOM() { const dom = new JSDOM('<!DOCTYPE html><html><body></body></html>'); global.DOMParser = dom.window.DOMParser; global.Document = dom.window.Document; global.Element = dom.window.Element; global.HTMLElement = dom.window.HTMLElement; global.document = dom.window.document; } function patchXHR(token?: string) { global.XMLHttpRequest = XMLHttpRequest; const proto = XMLHttpRequest.prototype; const originalOpen = proto.open; proto.open = function (method: string, url: string, ...args: any[]) { // if no protocol ("http:", "https:", etc), assume relative if (!/^[a-z][a-z\d+\-.]*:/.test(url)) { url = new URL(url, window.location.origin).href; } return originalOpen.apply(this, [method, url, ...args]); } if (token) { const originalSend = proto.send; proto.send = function (body?: any) { this.setRequestHeader("Authorization", `Bearer ${token}`); return originalSend.apply(this, [body]); } } } function patchGetJson(token: string) { const originalGetJson = rest.GetJson; (rest as any).GetJson = async function patchedGetJson<T>( url: string, body?: IRequestBody, options?: IRestOptions ): Promise<T> { const updatedOptions: IRestOptions = { ...options, headers: { ...(options?.headers || {}), Authorization: `Bearer ${token}` } }; return originalGetJson(url, body, updatedOptions); }; } export const mochaHooks = { beforeAll, afterAll };