Skip to content

Commit

Permalink
Add tests
Browse files Browse the repository at this point in the history
  • Loading branch information
BobSilent committed Jun 4, 2024
1 parent 1af3348 commit 8e2ed87
Show file tree
Hide file tree
Showing 2 changed files with 107 additions and 14 deletions.
28 changes: 14 additions & 14 deletions extension/task/utils/resolveAzureDevOpsIdentities.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ export async function resolveAzureDevOpsIdentities(organizationUrl: URL, inputs:
* In Azure DevOps terms, hosted environment is also known as "Azure DevOps Services" and on-premise environment is known as
* "Team Foundation Server" or "Azure DevOps Server".
*/
function isHostedAzureDevOps(uri: URL): boolean {
export function isHostedAzureDevOps(uri: URL): boolean {
const hostname = uri.hostname.toLowerCase();
return hostname === 'dev.azure.com' || hostname.endsWith('.visualstudio.com');
}
Expand Down Expand Up @@ -84,10 +84,10 @@ async function querySubject(organizationUrl: URL, email: string): Promise<IIdent
* @returns
*/
async function querySubjectOnPrem(organizationUrl: URL, email: string): Promise<IIdentity | undefined> {
var url = `${organizationUrl}_apis/identities?searchFilter=MailAddress&queryMembership=None&filterValue=${email}`;
tl.debug(`GET ${url}`);
const url = `${organizationUrl}_apis/identities?searchFilter=MailAddress&queryMembership=None&filterValue=${email}`;
tl.debug(`GET ${url}`);
try {
var response = await axios.get(url, {
const response = await axios.get(url, {
headers: {
Authorization: `Basic ${encodeBase64("PAT:" + tl.getVariable("System.AccessToken"))}`,
Accept: "application/json;api-version=5.0",
Expand All @@ -101,7 +101,7 @@ async function querySubjectOnPrem(organizationUrl: URL, email: string): Promise<
input: email}
}
} catch (error) {
var responseStatusCode = error?.response?.status;
const responseStatusCode = error?.response?.status;
tl.debug(`HTTP Response Status: ${responseStatusCode}`)
if (responseStatusCode > 400 && responseStatusCode < 500) {
tl.debug(`Access token is ${tl.getVariable("System.AccessToken")?.length > 0 ? "not" : ""} null or empty.`);
Expand All @@ -116,16 +116,16 @@ async function querySubjectOnPrem(organizationUrl: URL, email: string): Promise<

/**
* * Make the HTTP Request for a hosted Azure DevOps Service, to resolve an email to an IIdentity
* @param organization
* @param email
* @returns
* @param organization
* @param email
* @returns
*/
async function querySubjectHosted(organization: string, email: string): Promise<IIdentity | undefined> {
// make HTTP request
var url = `https://vssps.dev.azure.com/${organization}/_apis/graph/subjectquery`;
tl.debug(`GET ${url}`);
const url = `https://vssps.dev.azure.com/${organization}/_apis/graph/subjectquery`;
tl.debug(`GET ${url}`);
try {
var response = await axios.post(url, {
const response = await axios.post(url, {
headers: {
Authorization: `Basic ${encodeBase64("PAT:" + tl.getVariable("System.AccessToken"))}`,
Accept: "application/json;api-version=6.0-preview.1",
Expand All @@ -138,15 +138,15 @@ async function querySubjectHosted(organization: string, email: string): Promise<
});

if (isSuccessStatusCode(response.status)) {
var descriptor: string = response.data.value[0]?.descriptor || "";
var id = decodeBase64(descriptor.substring(descriptor.indexOf(".") + 1))
const descriptor: string = response.data.value[0]?.descriptor || "";
const id = decodeBase64(descriptor.substring(descriptor.indexOf(".") + 1))
return {
id: id,
displayName: response.data.value[0]?.displayName,
input: email}
}
} catch (error) {
var responseStatusCode = error?.response?.status;
const responseStatusCode = error?.response?.status;
tl.debug(`HTTP Response Status: ${responseStatusCode}`)
if (responseStatusCode > 400 && responseStatusCode < 500) {
tl.debug(`Access token is ${tl.getVariable("System.AccessToken")?.length > 0 ? "not" : ""} null or empty.`);
Expand Down
93 changes: 93 additions & 0 deletions extension/tests/utils/resolveAzureDevOpsIdentities.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
import { isHostedAzureDevOps, resolveAzureDevOpsIdentities } from "../../task/utils/resolveAzureDevOpsIdentities";
import { describe } from "node:test";
import axios from "axios";

describe("isHostedAzureDevOps", () => {
it("Old visualstudio url is hosted.", () => {
const url = new URL("https://example.visualstudio.com/abc")
const result = isHostedAzureDevOps(url);

expect(result).toBeTruthy();
});
it("Dev Azure url is hosted.", () => {
const url = new URL("https://dev.azure.com/example")
const result = isHostedAzureDevOps(url);

expect(result).toBeTruthy();
});
it("private url is not hosted.", () => {
const url = new URL("https://tfs.example.com/tfs/Collection")
const result = isHostedAzureDevOps(url);

expect(result).toBeFalsy();
});
});


jest.mock('axios');
const mockedAxios = axios as jest.Mocked<typeof axios>;

const aliceOnPrem = {
id: "any id",
email: "[email protected]",
providerDisplayName: "Alice"
}

const aliceHostedId = "any Id"
const aliceHosted = {
descriptor: "aad." + Buffer.from(aliceHostedId, 'utf8').toString('base64'),
email: "[email protected]",
providerDisplayName: "Alice"
}

describe("resolveAzureDevOpsIdentities", () => {
it("No email input, is directly returned.", async () => {
const url = new URL("https://example.visualstudio.com/abc")

const input = ["be9321e2-f404-4ffa-8d6b-44efddb04865"];
const results = await resolveAzureDevOpsIdentities(url, input);

const outputs = results.map(identity => identity.id);
expect(outputs).toHaveLength(1);
expect(outputs).toContain(input[0]);
});
it("successfully resolve id for azure devops server", async () => {
const url = new URL("https://example.onprem.com/abc")

// Provide the data object to be returned
mockedAxios.get.mockResolvedValue({
data: {
count: 1,
value: [aliceOnPrem],
},
status: 200,
});

const input = [aliceOnPrem.email];
const results = await resolveAzureDevOpsIdentities(url, input);

const outputs = results.map(identity => identity.id);
expect(outputs).toHaveLength(1);
expect(outputs).toContain(aliceOnPrem.id);
});
it("successfully resolve id for hosted azure devops", async () => {
const url = new URL("https://dev.azure.com/exampleorganization")


// Provide the data object to be returned
mockedAxios.post.mockResolvedValue({
data: {
count: 1,
value: [aliceHosted],
},
status: 200,
});

const input = [aliceHosted.email];
const results = await resolveAzureDevOpsIdentities(url, input);

const outputs = results.map(identity => identity.id);
expect(outputs).toHaveLength(1);
expect(outputs).toContain(aliceHostedId);
});
});

0 comments on commit 8e2ed87

Please sign in to comment.