test: Seed GCal test credentials (#12596)
* Seed GCal test credentials * Set yml .env to secrets * Switch to vars * Add error messages * Set error message * Error messages * Change .env to secrets * Run db-seed even with cache * Add with DATABASE_URL * Set DB URL * Set DB URL * Inputs DB URL * Move database URL to with block * Create env under yarn db-studio * Fix typo * WIP * WIP * WIP * WIP * WIP * Add credential console log * Hit cache * Add logs * Remove echo * Run on ubuntu latest * Don't cache db * Uncache * WIP * WIP * Change back to buildjet * Seed GCal keys in test * Test uses GCal keys * Parse keys * WIP * WIP * WIP * WIP * WIP * WIP * WIP * WIP * WIP * WIP * WIP * WIP * WIP * WIP * WIP * WIP * WIP * WIP * WIP * WIP * WIP * WIP * WIP * Clean up * Type fix * Clean up * Clean up
This commit is contained in:
parent
b384e4a9d8
commit
4faad64978
|
@ -272,6 +272,8 @@ E2E_TEST_APPLE_CALENDAR_PASSWORD=""
|
|||
E2E_TEST_CALCOM_QA_EMAIL="qa@example.com"
|
||||
# Replace with your own password
|
||||
E2E_TEST_CALCOM_QA_PASSWORD="password"
|
||||
E2E_TEST_CALCOM_QA_GCAL_CREDENTIALS=
|
||||
E2E_TEST_CALCOM_GCAL_KEYS=
|
||||
|
||||
# - APP CREDENTIAL SYNC ***********************************************************************************
|
||||
# Used for self-hosters that are implementing Cal.com into their applications that already have certain integrations
|
||||
|
|
|
@ -17,10 +17,15 @@ runs:
|
|||
cache-name: cache-db
|
||||
key-1: ${{ hashFiles('packages/prisma/schema.prisma', 'packages/prisma/migrations/**/**.sql', 'packages/prisma/*.ts') }}
|
||||
key-2: ${{ github.event.pull_request.number || github.ref }}
|
||||
DATABASE_URL: ${{ inputs.DATABASE_URL }}
|
||||
E2E_TEST_CALCOM_QA_EMAIL: ${{ inputs.E2E_TEST_CALCOM_QA_EMAIL }}
|
||||
E2E_TEST_CALCOM_QA_PASSWORD: ${{ inputs.E2E_TEST_CALCOM_QA_PASSWORD }}
|
||||
E2E_TEST_CALCOM_QA_GCAL_CREDENTIALS: ${{ inputs.E2E_TEST_CALCOM_QA_GCAL_CREDENTIALS }}
|
||||
with:
|
||||
path: ${{ inputs.path }}
|
||||
key: ${{ runner.os }}-${{ env.cache-name }}-${{ inputs.path }}-${{ env.key-1 }}-${{ env.key-2 }}
|
||||
- run: yarn db-seed
|
||||
DATABASE_URL: ${{ inputs.DATABASE_URL }}
|
||||
- run: echo ${{ env.E2E_TEST_CALCOM_QA_GCAL_CREDENTIALS }} && yarn db-seed
|
||||
if: steps.cache-db.outputs.cache-hit != 'true'
|
||||
shell: bash
|
||||
- name: Postgres Dump Backup
|
||||
|
|
|
@ -33,6 +33,12 @@ jobs:
|
|||
- uses: ./.github/actions/yarn-install
|
||||
- uses: ./.github/actions/yarn-playwright-install
|
||||
- uses: ./.github/actions/cache-db
|
||||
env:
|
||||
DATABASE_URL: ${{ secrets.CI_DATABASE_URL }}
|
||||
E2E_TEST_CALCOM_QA_EMAIL: ${{ secrets.E2E_TEST_CALCOM_QA_EMAIL }}
|
||||
E2E_TEST_CALCOM_QA_PASSWORD: ${{ secrets.E2E_TEST_CALCOM_QA_PASSWORD }}
|
||||
E2E_TEST_CALCOM_QA_GCAL_CREDENTIALS: ${{ secrets.E2E_TEST_CALCOM_QA_GCAL_CREDENTIALS }}
|
||||
E2E_TEST_CALCOM_GCAL_KEYS: ${{ secrets.E2E_TEST_CALCOM_GCAL_KEYS }}
|
||||
- uses: ./.github/actions/cache-build
|
||||
- name: Run Tests
|
||||
run: yarn e2e:app-store --shard=${{ matrix.shard }}/${{ strategy.job-total }}
|
||||
|
@ -43,6 +49,10 @@ jobs:
|
|||
DEPLOYSENTINEL_API_KEY: ${{ secrets.DEPLOYSENTINEL_API_KEY }}
|
||||
E2E_TEST_APPLE_CALENDAR_EMAIL: ${{ secrets.E2E_TEST_APPLE_CALENDAR_EMAIL }}
|
||||
E2E_TEST_APPLE_CALENDAR_PASSWORD: ${{ secrets.E2E_TEST_APPLE_CALENDAR_PASSWORD }}
|
||||
E2E_TEST_CALCOM_QA_EMAIL: ${{ secrets.E2E_TEST_CALCOM_QA_EMAIL }}
|
||||
E2E_TEST_CALCOM_QA_PASSWORD: ${{ secrets.E2E_TEST_CALCOM_QA_PASSWORD }}
|
||||
E2E_TEST_CALCOM_QA_GCAL_CREDENTIALS: ${{ secrets.E2E_TEST_CALCOM_QA_GCAL_CREDENTIALS }}
|
||||
E2E_TEST_CALCOM_GCAL_KEYS: ${{ secrets.E2E_TEST_CALCOM_GCAL_KEYS }}
|
||||
E2E_TEST_MAILHOG_ENABLED: ${{ vars.E2E_TEST_MAILHOG_ENABLED }}
|
||||
GOOGLE_API_CREDENTIALS: ${{ secrets.CI_GOOGLE_API_CREDENTIALS }}
|
||||
GOOGLE_LOGIN_ENABLED: ${{ vars.CI_GOOGLE_LOGIN_ENABLED }}
|
||||
|
|
|
@ -9,6 +9,10 @@ env:
|
|||
DATABASE_URL: ${{ secrets.CI_DATABASE_URL }}
|
||||
E2E_TEST_APPLE_CALENDAR_EMAIL: ${{ secrets.E2E_TEST_APPLE_CALENDAR_EMAIL }}
|
||||
E2E_TEST_APPLE_CALENDAR_PASSWORD: ${{ secrets.E2E_TEST_APPLE_CALENDAR_PASSWORD }}
|
||||
E2E_TEST_CALCOM_QA_EMAIL: ${{ secrets.E2E_TEST_CALCOM_QA_EMAIL }}
|
||||
E2E_TEST_CALCOM_QA_PASSWORD: ${{ secrets.E2E_TEST_CALCOM_QA_PASSWORD }}
|
||||
E2E_TEST_CALCOM_QA_GCAL_CREDENTIALS: ${{ secrets.E2E_TEST_CALCOM_QA_GCAL_CREDENTIALS }}
|
||||
E2E_TEST_CALCOM_GCAL_KEYS: ${{ secrets.E2E_TEST_CALCOM_GCAL_KEYS }}
|
||||
GOOGLE_API_CREDENTIALS: ${{ secrets.CI_GOOGLE_API_CREDENTIALS }}
|
||||
GOOGLE_LOGIN_ENABLED: ${{ vars.CI_GOOGLE_LOGIN_ENABLED }}
|
||||
NEXTAUTH_SECRET: ${{ secrets.CI_NEXTAUTH_SECRET }}
|
||||
|
|
|
@ -4,7 +4,7 @@ import type { Page } from "@playwright/test";
|
|||
import dayjs from "@calcom/dayjs";
|
||||
import { APP_CREDENTIAL_SHARING_ENABLED } from "@calcom/lib/constants";
|
||||
import prisma from "@calcom/prisma";
|
||||
import type { Prisma } from "@calcom/prisma/client";
|
||||
import type { CredentialPayload } from "@calcom/types/Credential";
|
||||
import { test } from "@calcom/web/playwright/lib/fixtures";
|
||||
import { selectSecondAvailableTimeSlotNextMonth } from "@calcom/web/playwright/lib/testUtils";
|
||||
|
||||
|
@ -15,12 +15,30 @@ import { createBookingAndFetchGCalEvent, deleteBookingAndEvent, assertValueExist
|
|||
test.describe("Google Calendar", async () => {
|
||||
test.describe("Test using the primary calendar", async () => {
|
||||
let qaUsername: string;
|
||||
let qaGCalCredential: Prisma.CredentialGetPayload<{ select: { id: true } }>;
|
||||
let qaGCalCredential: CredentialPayload;
|
||||
test.beforeAll(async () => {
|
||||
let runIntegrationTest = false;
|
||||
const errorMessage = "Could not run test";
|
||||
|
||||
test.skip(!!APP_CREDENTIAL_SHARING_ENABLED, "Credential sharing enabled");
|
||||
|
||||
if (process.env.E2E_TEST_CALCOM_GCAL_KEYS) {
|
||||
const gCalKeys = JSON.parse(process.env.E2E_TEST_CALCOM_GCAL_KEYS);
|
||||
await prisma.app.update({
|
||||
where: {
|
||||
slug: "google-calendar",
|
||||
},
|
||||
data: {
|
||||
keys: gCalKeys,
|
||||
},
|
||||
});
|
||||
} else {
|
||||
test.skip(!process.env.E2E_TEST_CALCOM_GCAL_KEYS, "GCal keys not found");
|
||||
}
|
||||
|
||||
test.skip(!process.env.E2E_TEST_CALCOM_QA_EMAIL, "QA email not found");
|
||||
test.skip(!process.env.E2E_TEST_CALCOM_QA_PASSWORD, "QA password not found");
|
||||
|
||||
if (process.env.E2E_TEST_CALCOM_QA_EMAIL && process.env.E2E_TEST_CALCOM_QA_PASSWORD) {
|
||||
qaGCalCredential = await prisma.credential.findFirstOrThrow({
|
||||
where: {
|
||||
|
@ -29,63 +47,59 @@ test.describe("Google Calendar", async () => {
|
|||
},
|
||||
type: metadata.type,
|
||||
},
|
||||
select: {
|
||||
id: true,
|
||||
include: {
|
||||
user: {
|
||||
select: {
|
||||
email: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
test.skip(!qaGCalCredential, "Google QA credential not found");
|
||||
|
||||
const qaUserQuery = await prisma.user.findFirstOrThrow({
|
||||
where: {
|
||||
email: process.env.E2E_TEST_CALCOM_QA_EMAIL,
|
||||
},
|
||||
select: {
|
||||
id: true,
|
||||
username: true,
|
||||
},
|
||||
});
|
||||
|
||||
test.skip(!qaUserQuery, "QA user not found");
|
||||
|
||||
assertValueExists(qaUserQuery.username, "qaUsername");
|
||||
qaUsername = qaUserQuery.username;
|
||||
|
||||
test.skip(!qaUsername, "QA username not found");
|
||||
|
||||
const googleCalendarService = new GoogleCalendarService(qaGCalCredential);
|
||||
|
||||
const calendars = await googleCalendarService.listCalendars();
|
||||
|
||||
const primaryCalendarName = calendars.find((calendar) => calendar.primary)?.name;
|
||||
assertValueExists(primaryCalendarName, "primaryCalendarName");
|
||||
|
||||
await prisma.destinationCalendar.upsert({
|
||||
where: {
|
||||
userId: qaUserQuery.id,
|
||||
externalId: primaryCalendarName,
|
||||
eventTypeId: undefined,
|
||||
},
|
||||
update: {},
|
||||
create: {
|
||||
integration: "google_calendar",
|
||||
userId: qaUserQuery.id,
|
||||
externalId: primaryCalendarName,
|
||||
credentialId: qaGCalCredential.id,
|
||||
},
|
||||
});
|
||||
|
||||
if (qaGCalCredential && qaUsername) runIntegrationTest = true;
|
||||
}
|
||||
|
||||
test.skip(!runIntegrationTest, "QA user not found");
|
||||
});
|
||||
|
||||
test.beforeEach(async ({ page, users }) => {
|
||||
assertValueExists(process.env.E2E_TEST_CALCOM_QA_EMAIL, "qaEmail");
|
||||
|
||||
const qaUserStore = await users.set(process.env.E2E_TEST_CALCOM_QA_EMAIL);
|
||||
|
||||
await qaUserStore.apiLogin(process.env.E2E_TEST_CALCOM_QA_PASSWORD);
|
||||
|
||||
// Need to refresh keys from DB
|
||||
const refreshedCredential = await prisma.credential.findFirst({
|
||||
where: {
|
||||
id: qaGCalCredential?.id,
|
||||
},
|
||||
include: {
|
||||
user: {
|
||||
select: {
|
||||
email: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
assertValueExists(refreshedCredential, "refreshedCredential");
|
||||
|
||||
const googleCalendarService = new GoogleCalendarService(refreshedCredential);
|
||||
|
||||
const calendars = await googleCalendarService.listCalendars();
|
||||
|
||||
const primaryCalendarName = calendars.find((calendar) => calendar.primary)?.name;
|
||||
assertValueExists(primaryCalendarName, "primaryCalendarName");
|
||||
|
||||
await page.goto("/apps/installed/calendar");
|
||||
|
||||
await page.waitForSelector('[title*="Create events on"]');
|
||||
await page.locator('[title*="Create events on"]').locator("svg").click();
|
||||
await page.locator("#react-select-2-option-0-0").getByText(primaryCalendarName).click();
|
||||
test.skip(!runIntegrationTest, errorMessage);
|
||||
});
|
||||
|
||||
test("On new booking, event should be created on GCal", async ({ page }) => {
|
||||
|
|
|
@ -3,7 +3,7 @@ import { expect } from "@playwright/test";
|
|||
|
||||
import prisma from "@calcom/prisma";
|
||||
import type { Prisma } from "@calcom/prisma/client";
|
||||
import { bookFirstEvent } from "@calcom/web/playwright/lib/testUtils";
|
||||
import { bookTimeSlot, selectSecondAvailableTimeSlotNextMonth } from "@calcom/web/playwright/lib/testUtils";
|
||||
|
||||
import metadata from "../_metadata";
|
||||
import GoogleCalendarService from "../lib/CalendarService";
|
||||
|
@ -20,8 +20,13 @@ export const createBookingAndFetchGCalEvent = async (
|
|||
qaGCalCredential: Prisma.CredentialGetPayload<{ select: { id: true } }> | null,
|
||||
qaUsername: string
|
||||
) => {
|
||||
await page.goto(`/${qaUsername}`);
|
||||
await bookFirstEvent(page);
|
||||
await page.goto(`/${qaUsername}/15min`);
|
||||
await selectSecondAvailableTimeSlotNextMonth(page);
|
||||
await bookTimeSlot(page);
|
||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||
// @ts-ignore
|
||||
await page.waitForNavigation({ state: "networkidle" });
|
||||
await page.locator("[data-testid=success-page]");
|
||||
|
||||
const bookingUrl = await page.url();
|
||||
const bookingUid = bookingUrl.match(/booking\/([^\/?]+)/);
|
||||
|
@ -64,6 +69,7 @@ export const createBookingAndFetchGCalEvent = async (
|
|||
}),
|
||||
]);
|
||||
assertValueExists(gCalReference, "gCalReference");
|
||||
|
||||
assertValueExists(booking, "booking");
|
||||
|
||||
// Need to refresh keys from DB
|
||||
|
|
|
@ -415,7 +415,7 @@ const loadUsers = async (eventType: NewBookingEventType, dynamicUserList: string
|
|||
}
|
||||
};
|
||||
|
||||
async function ensureAvailableUsers(
|
||||
export async function ensureAvailableUsers(
|
||||
eventType: Awaited<ReturnType<typeof getEventTypesFromDB>> & {
|
||||
users: IsFixedAwareUser[];
|
||||
},
|
||||
|
|
|
@ -10,6 +10,7 @@ import prisma from ".";
|
|||
export async function createUserAndEventType({
|
||||
user,
|
||||
eventTypes = [],
|
||||
credentials,
|
||||
}: {
|
||||
user: {
|
||||
email: string;
|
||||
|
@ -27,6 +28,11 @@ export async function createUserAndEventType({
|
|||
_numBookings?: number;
|
||||
}
|
||||
>;
|
||||
credentials?: ({
|
||||
type: string;
|
||||
key: Prisma.JsonObject;
|
||||
appId: string;
|
||||
} | null)[];
|
||||
}) {
|
||||
const userData = {
|
||||
...user,
|
||||
|
@ -144,5 +150,20 @@ export async function createUserAndEventType({
|
|||
}
|
||||
}
|
||||
console.log("👤 User with it's event-types and bookings created", theUser.email);
|
||||
|
||||
if (credentials) {
|
||||
for (const credential of credentials) {
|
||||
if (credential) {
|
||||
await prisma.credential.create({
|
||||
data: {
|
||||
...credential,
|
||||
userId: theUser.id,
|
||||
},
|
||||
});
|
||||
|
||||
console.log(`🔑 ${credential.type} credentials created for ${theUser.email}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
return theUser;
|
||||
}
|
||||
|
|
|
@ -455,21 +455,32 @@ async function main() {
|
|||
},
|
||||
});
|
||||
|
||||
await createUserAndEventType({
|
||||
user: {
|
||||
email: process.env.E2E_TEST_CALCOM_QA_EMAIL || "qa@example.com",
|
||||
password: process.env.E2E_TEST_CALCOM_QA_PASSWORD || "qa",
|
||||
username: "qa",
|
||||
name: "QA Example",
|
||||
},
|
||||
eventTypes: [
|
||||
{
|
||||
title: "15min",
|
||||
slug: "15min",
|
||||
length: 15,
|
||||
if (!!(process.env.E2E_TEST_CALCOM_QA_EMAIL && process.env.E2E_TEST_CALCOM_QA_PASSWORD)) {
|
||||
await createUserAndEventType({
|
||||
user: {
|
||||
email: process.env.E2E_TEST_CALCOM_QA_EMAIL || "qa@example.com",
|
||||
password: process.env.E2E_TEST_CALCOM_QA_PASSWORD || "qa",
|
||||
username: "qa",
|
||||
name: "QA Example",
|
||||
},
|
||||
],
|
||||
});
|
||||
eventTypes: [
|
||||
{
|
||||
title: "15min",
|
||||
slug: "15min",
|
||||
length: 15,
|
||||
},
|
||||
],
|
||||
credentials: [
|
||||
!!process.env.E2E_TEST_CALCOM_QA_GCAL_CREDENTIALS
|
||||
? {
|
||||
type: "google_calendar",
|
||||
key: JSON.parse(process.env.E2E_TEST_CALCOM_QA_GCAL_CREDENTIALS) as Prisma.JsonObject,
|
||||
appId: "google-calendar",
|
||||
}
|
||||
: null,
|
||||
],
|
||||
});
|
||||
}
|
||||
|
||||
await createTeamAndAddUsers(
|
||||
{
|
||||
|
|
|
@ -239,6 +239,8 @@
|
|||
"E2E_TEST_APPLE_CALENDAR_PASSWORD",
|
||||
"E2E_TEST_CALCOM_QA_EMAIL",
|
||||
"E2E_TEST_CALCOM_QA_PASSWORD",
|
||||
"E2E_TEST_CALCOM_QA_GCAL_CREDENTIALS",
|
||||
"E2E_TEST_CALCOM_GCAL_KEYS",
|
||||
"E2E_TEST_MAILHOG_ENABLED",
|
||||
"E2E_TEST_OIDC_CLIENT_ID",
|
||||
"E2E_TEST_OIDC_CLIENT_SECRET",
|
||||
|
|
Loading…
Reference in New Issue
Block a user