Skip to content

Commit

Permalink
Add integration tests.
Browse files Browse the repository at this point in the history
  • Loading branch information
dany-pellerin committed Dec 17, 2024
1 parent 1d70c16 commit 74352db
Show file tree
Hide file tree
Showing 14 changed files with 1,156 additions and 61 deletions.
7 changes: 6 additions & 1 deletion jest.config.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
/** @type {import('jest').Config} */
const config = {
testEnvironment: "jsdom",
setupFiles: ["<rootDir>/setup-jest.js"],
resetMocks: false,
setupFiles: ["<rootDir>/setup-jest.js", "jest-localstorage-mock"],
setupFilesAfterEnv: ["<rootDir>/setup-env.js"],
testEnvironmentOptions: {
customExportConditions: [""],
},
};

module.exports = config;
4 changes: 3 additions & 1 deletion lib/edge/site.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ type AuctionConfig = {
type SiteResponse = {
interestGroupPixel: string;
auctionConfig?: AuctionConfig | null;
auctionConfigURL?: string;
getTopicsURL: string;
};

Expand All @@ -40,5 +41,6 @@ function SiteFromCache(config: Required<OptableConfig>): SiteResponse | null {
return ls.getSite();
}

export { Site, SiteResponse, SiteFromCache, Size, AuctionConfig };
export { Site, SiteFromCache };
export default Site;
export type { SiteResponse, Size, AuctionConfig };
3 changes: 2 additions & 1 deletion lib/edge/targeting.ts
Original file line number Diff line number Diff line change
Expand Up @@ -103,5 +103,6 @@ function TargetingKeyValues(tdata: TargetingResponse | null): TargetingKeyValues
return result;
}

export { Targeting, TargetingFromCache, TargetingClearCache, TargetingResponse, PrebidORTB2, TargetingKeyValues };
export { Targeting, TargetingFromCache, TargetingClearCache, PrebidORTB2, TargetingKeyValues };
export default Targeting;
export type { TargetingResponse };
3 changes: 2 additions & 1 deletion lib/edge/tokenize.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,5 +23,6 @@ function Tokenize(config: Required<OptableConfig>, id: string): Promise<Tokenize
});
}

export { Tokenize, TokenizeRequest, TokenizeResponse };
export { Tokenize };
export default Tokenize;
export type { TokenizeRequest, TokenizeResponse };
1 change: 1 addition & 0 deletions lib/edge/uid2_token.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,4 @@ function Uid2Token(config: Required<OptableConfig>, id: string): Promise<Uid2Tok

export { Uid2Token };
export default Uid2Token;
export type { Uid2TokenResponse };
49 changes: 0 additions & 49 deletions lib/sdk.test.js

This file was deleted.

253 changes: 253 additions & 0 deletions lib/sdk.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,253 @@
import OptableSDK from "./sdk";
import { TEST_HOST, TEST_SITE } from "./test/mocks";

describe("eid", () => {
test("is correct", () => {
const expected = "e:a665a45920422f9d417e4867efdc4fb8a04a1f3fff1fa07e998e86f7f7a27ae3";

expect(OptableSDK.eid("123")).toEqual(expected);
expect(OptableSDK.eid("123 ")).toEqual(expected);
expect(OptableSDK.eid(" 123")).toEqual(expected);
expect(OptableSDK.eid(" 123 ")).toEqual(expected);
});

test("ignores case", () => {
const var1 = "[email protected]";
const var2 = "[email protected]";
const var3 = "[email protected]";
const var4 = "[email protected]";
const eid = OptableSDK.eid(var1);

expect(eid).toEqual(OptableSDK.eid(var2));
expect(eid).toEqual(OptableSDK.eid(var3));
expect(eid).toEqual(OptableSDK.eid(var4));
});
});

describe("cid", () => {
test("rejects non-string id", () => {
expect(() => OptableSDK.cid(1 as unknown as string)).toThrow();
});

test("prefixes with c: by default", () => {
expect(OptableSDK.cid("abc")).toEqual("c:abc");
});

test("accepts a custom variant", () => {
expect(OptableSDK.cid("abc", 0)).toEqual("c:abc");
for (let i = 1; i < 10; i++) {
expect(OptableSDK.cid("abc", i)).toEqual(`c${i}:abc`);
}

expect(() => OptableSDK.cid("abc", -1)).toThrow();
expect(() => OptableSDK.cid("abc", 10)).toThrow();
expect(() => OptableSDK.cid("abc", "1" as unknown as number)).toThrow();
});

test("trim spaces", () => {
expect(OptableSDK.cid(" \n abc\t")).toEqual("c:abc");
});

test("preserve case", () => {
expect(OptableSDK.cid("ABCD")).toEqual("c:ABCD");
});
});

const defaultConfig = {
host: TEST_HOST,
site: TEST_SITE,
};

describe("Breaking change detection: if typescript complains or a test fails it's likely a breaking change has occurred.", () => {
beforeEach(() => localStorage.clear());

test("TEST SHOULD NEVER NEED TO BE UPDATED, UNLESS MAJOR VERSION UPDATE: constructor with cookies and initPassport set", async () => {
new OptableSDK({
...defaultConfig,
cookies: false,
initPassport: false,
});
});

test("TEST SHOULD NEVER NEED TO BE UPDATED, UNLESS MAJOR VERSION UPDATE: constructor not set", async () => {
new OptableSDK({ ...defaultConfig });
});

test("TEST SHOULD NEVER NEED TO BE UPDATED, UNLESS MAJOR VERSION UPDATE: identify", async () => {
await new OptableSDK({ ...defaultConfig }).identify("c:a1a335b8216658319f96a4b0c718557ba41dd1f5");
await new OptableSDK({ ...defaultConfig }).identify(
"c:a1a335b8216658319f96a4b0c718557ba41dd1f5",
"other-identifier"
);
});

test("TEST SHOULD NEVER NEED TO BE UPDATED, UNLESS MAJOR VERSION UPDATE: witness", async () => {
await new OptableSDK({ ...defaultConfig }).witness("event");
await new OptableSDK({ ...defaultConfig }).witness("event", { property: "value" });
});

test("TEST SHOULD NEVER NEED TO BE UPDATED, UNLESS MAJOR VERSION UPDATE: profile", async () => {
await new OptableSDK({ ...defaultConfig }).profile({
propString: "",
propBool: true,
propNumber: 3,
});
});

test("TEST SHOULD NEVER NEED TO BE UPDATED, UNLESS MAJOR VERSION UPDATE: targeting", async () => {
const result = await new OptableSDK({ ...defaultConfig }).targeting("c:a1a335b8216658319f96a4b0c718557ba41dd1f5");
["audience", "user"].forEach((key) => expect(Object.keys(result)).toContain(key));
});

test("TEST SHOULD NEVER NEED TO BE UPDATED, UNLESS MAJOR VERSION UPDATE: uid2Token", async () => {
await new OptableSDK({ ...defaultConfig }).uid2Token("c:a1a335b8216658319f96a4b0c718557ba41dd1f5");
});

test("TEST SHOULD NEVER NEED TO BE UPDATED, UNLESS MAJOR VERSION UPDATE: targetingFromCache", async () => {
const result = new OptableSDK({ ...defaultConfig }).targetingFromCache();
expect(result).toBeNull();

await new OptableSDK({ ...defaultConfig }).targeting("c:a1a335b8216658319f96a4b0c718557ba41dd1f5");
const result2 = new OptableSDK({ ...defaultConfig }).targetingFromCache();
expect(typeof result2).toBe("object");
});

test("TEST SHOULD NEVER NEED TO BE UPDATED, UNLESS MAJOR VERSION UPDATE: site", async () => {
await new OptableSDK({ ...defaultConfig }).site();
});

test("TEST SHOULD NEVER NEED TO BE UPDATED, UNLESS MAJOR VERSION UPDATE: siteFromCache", () => {
new OptableSDK({ ...defaultConfig }).siteFromCache();
});

test("TEST SHOULD NEVER NEED TO BE UPDATED, UNLESS MAJOR VERSION UPDATE: targetingClearCache", () => {
new OptableSDK({ ...defaultConfig }).targetingClearCache();
});

test("TEST SHOULD NEVER NEED TO BE UPDATED, UNLESS MAJOR VERSION UPDATE: prebidORTB2", async () => {
const result = await new OptableSDK({ ...defaultConfig }).prebidORTB2();
expect(Object.keys(result)).toContain("user");
});

test("TEST SHOULD NEVER NEED TO BE UPDATED, UNLESS MAJOR VERSION UPDATE: prebidORTB2FromCache", () => {
new OptableSDK({ ...defaultConfig }).prebidORTB2FromCache();
});

test("TEST SHOULD NEVER NEED TO BE UPDATED, UNLESS MAJOR VERSION UPDATE: targetingKeyValues", async () => {
await new OptableSDK({ ...defaultConfig }).targetingKeyValues();
});

test("TEST SHOULD NEVER NEED TO BE UPDATED, UNLESS MAJOR VERSION UPDATE: targetingKeyValuesFromCache", () => {
new OptableSDK({ ...defaultConfig }).targetingKeyValuesFromCache();
});

test("TEST SHOULD NEVER NEED TO BE UPDATED, UNLESS MAJOR VERSION UPDATE: tokenize", async () => {
await new OptableSDK({ ...defaultConfig }).tokenize("myid");
});

test("TEST SHOULD NEVER NEED TO BE UPDATED, UNLESS MAJOR VERSION UPDATE: eid", async () => {
const myId = OptableSDK.eid("myid");
expect(typeof myId).toBe("string");
});

test("TEST SHOULD NEVER NEED TO BE UPDATED, UNLESS MAJOR VERSION UPDATE: sha256", async () => {
const shaValue = OptableSDK.sha256("someValue");
expect(typeof shaValue).toBe("string");
});

test("TEST SHOULD NEVER NEED TO BE UPDATED, UNLESS MAJOR VERSION UPDATE: cid", async () => {
const cidValue = OptableSDK.cid("someValue");
expect(typeof cidValue).toBe("string");

const cidValueWithVariant = OptableSDK.cid("someValue", 4);
expect(typeof cidValueWithVariant).toBe("string");
});

test("TEST SHOULD NEVER NEED TO BE UPDATED, UNLESS MAJOR VERSION UPDATE: TargetingKeyValues", async () => {
const result = OptableSDK.TargetingKeyValues({ audience: [], user: [] });
expect(typeof result).toBe("object");
OptableSDK.TargetingKeyValues({ audience: [] });
OptableSDK.TargetingKeyValues({ user: [] });
OptableSDK.TargetingKeyValues({});
});

test("TEST SHOULD NEVER NEED TO BE UPDATED, UNLESS MAJOR VERSION UPDATE: PrebidORTB2", async () => {
const result = OptableSDK.PrebidORTB2({ audience: [], user: [] });
expect(typeof result).toBe("object");
expect(Object.keys(result)).toContain("user");
});
});

describe("SDK signature does not change for public functions", () => {
test("constructor with cookies and initPassport set to false initializes without localStorage", async () => {
const sdk = new OptableSDK({
...defaultConfig,
cookies: false,
initPassport: false,
});
expect(sdk).toBeInstanceOf(OptableSDK);
expect(sdk.dcn).toEqual({ host: "hostmock.com", site: "site", cookies: false, initPassport: false });
await sdk["init"];
expect(localStorage.setItem).toBeCalledTimes(0);
});

test("constructor with cookies and initPassport properties not provided initializes with localStorage and cookies", async () => {
const fetchMock = jest.spyOn(window, "fetch");
const sdk = new OptableSDK({ ...defaultConfig });
expect(sdk).toBeInstanceOf(OptableSDK);
expect(sdk.dcn).toEqual({ host: "hostmock.com", site: "site", cookies: true, initPassport: true });
await sdk["init"];
expect(window.localStorage.setItem).toBeCalledTimes(1);
expect(window.localStorage.setItem).toHaveBeenCalledWith(
expect.stringContaining("OPTABLE_SITE"),
expect.objectContaining({})
);

expect(fetchMock).toHaveBeenLastCalledWith(
expect.objectContaining({
method: "GET",
bodyUsed: false,
url: expect.stringContaining("config?osdk=web-0.0.0-experimental&cookies=yes"),
})
);
});

test("identify", async () => {
const fetchMock = jest.spyOn(window, "fetch");
const sdk = new OptableSDK({ ...defaultConfig });

await sdk.identify("c:a1a335b8216658319f96a4b0c718557ba41dd1f5");
expect(fetchMock).toHaveBeenLastCalledWith(
expect.objectContaining({
method: "POST",
_bodyText: '["c:a1a335b8216658319f96a4b0c718557ba41dd1f5"]',
url: expect.stringContaining("identify"),
})
);

await sdk.identify("[email protected]");
expect(fetchMock).toHaveBeenLastCalledWith(
expect.objectContaining({
method: "POST",
_bodyText: '["[email protected]"]',
url: expect.stringContaining("identify"),
})
);

await sdk.identify(
"[email protected]",
undefined as unknown as string,
null as unknown as string,
"",
0 as unknown as string,
"[email protected]"
);
expect(fetchMock).toHaveBeenLastCalledWith(
expect.objectContaining({
method: "POST",
_bodyText: '["[email protected]","[email protected]"]',
url: expect.stringContaining("identify"),
})
);
});
});
Loading

0 comments on commit 74352db

Please sign in to comment.