diff --git a/drizzle/seed.ts b/drizzle/seed.ts index 8cc53ba7..6113c6eb 100644 --- a/drizzle/seed.ts +++ b/drizzle/seed.ts @@ -1,7 +1,7 @@ import { nanoid } from "nanoid"; import { Chance } from "chance"; -import { post, user, tag, like, post_tag } from "../server/db/schema"; -import { sql } from "drizzle-orm"; +import { post, user, tag, like, post_tag, session } from "../server/db/schema"; +import { sql, eq } from "drizzle-orm"; import "dotenv/config"; @@ -9,6 +9,12 @@ import { drizzle, type PostgresJsDatabase } from "drizzle-orm/postgres-js"; import postgres from "postgres"; const DATABASE_URL = process.env.DATABASE_URL || ""; +// These can be removed in a follow on PR. Until this hits main we cant add E2E_USER_* stuff to the env. +const E2E_SESSION_ID = + process.env.E2E_USER_SESSION_ID || "df8a11f2-f20a-43d6-80a0-a213f1efedc1"; +const E2E_USER_ID = + process.env.E2E_USER_ID || "8e3179ce-f32b-4d0a-ba3b-234d66b836ad"; +const E2E_USER_EMAIL = process.env.E2E_USER_EMAIL || "e2e@codu.co"; if (!DATABASE_URL) { throw new Error("DATABASE_URL is not set"); @@ -16,266 +22,6 @@ if (!DATABASE_URL) { const client = postgres(DATABASE_URL, { max: 1 }); const db: PostgresJsDatabase = drizzle(client); -// chance.js only gives you full country name or abbreviation I need both -// opening a PR to give this option in change.js -const countries = [ - { name: "Afghanistan", abbreviation: "AF" }, - { name: "Åland Islands", abbreviation: "AX" }, - { name: "Albania", abbreviation: "AL" }, - { name: "Algeria", abbreviation: "DZ" }, - { name: "American Samoa", abbreviation: "AS" }, - { name: "Andorra", abbreviation: "AD" }, - { name: "Angola", abbreviation: "AO" }, - { name: "Anguilla", abbreviation: "AI" }, - { name: "Antarctica", abbreviation: "AQ" }, - { name: "Antigua & Barbuda", abbreviation: "AG" }, - { name: "Argentina", abbreviation: "AR" }, - { name: "Armenia", abbreviation: "AM" }, - { name: "Aruba", abbreviation: "AW" }, - { name: "Ascension Island", abbreviation: "AC" }, - { name: "Australia", abbreviation: "AU" }, - { name: "Austria", abbreviation: "AT" }, - { name: "Azerbaijan", abbreviation: "AZ" }, - { name: "Bahamas", abbreviation: "BS" }, - { name: "Bahrain", abbreviation: "BH" }, - { name: "Bangladesh", abbreviation: "BD" }, - { name: "Barbados", abbreviation: "BB" }, - { name: "Belarus", abbreviation: "BY" }, - { name: "Belgium", abbreviation: "BE" }, - { name: "Belize", abbreviation: "BZ" }, - { name: "Benin", abbreviation: "BJ" }, - { name: "Bermuda", abbreviation: "BM" }, - { name: "Bhutan", abbreviation: "BT" }, - { name: "Bolivia", abbreviation: "BO" }, - { name: "Bosnia & Herzegovina", abbreviation: "BA" }, - { name: "Botswana", abbreviation: "BW" }, - { name: "Brazil", abbreviation: "BR" }, - { name: "British Indian Ocean Territory", abbreviation: "IO" }, - { name: "British Virgin Islands", abbreviation: "VG" }, - { name: "Brunei", abbreviation: "BN" }, - { name: "Bulgaria", abbreviation: "BG" }, - { name: "Burkina Faso", abbreviation: "BF" }, - { name: "Burundi", abbreviation: "BI" }, - { name: "Cambodia", abbreviation: "KH" }, - { name: "Cameroon", abbreviation: "CM" }, - { name: "Canada", abbreviation: "CA" }, - { name: "Canary Islands", abbreviation: "IC" }, - { name: "Cape Verde", abbreviation: "CV" }, - { name: "Caribbean Netherlands", abbreviation: "BQ" }, - { name: "Cayman Islands", abbreviation: "KY" }, - { name: "Central African Republic", abbreviation: "CF" }, - { name: "Ceuta & Melilla", abbreviation: "EA" }, - { name: "Chad", abbreviation: "TD" }, - { name: "Chile", abbreviation: "CL" }, - { name: "China", abbreviation: "CN" }, - { name: "Christmas Island", abbreviation: "CX" }, - { name: "Cocos (Keeling) Islands", abbreviation: "CC" }, - { name: "Colombia", abbreviation: "CO" }, - { name: "Comoros", abbreviation: "KM" }, - { name: "Congo - Brazzaville", abbreviation: "CG" }, - { name: "Congo - Kinshasa", abbreviation: "CD" }, - { name: "Cook Islands", abbreviation: "CK" }, - { name: "Costa Rica", abbreviation: "CR" }, - { name: "Côte d'Ivoire", abbreviation: "CI" }, - { name: "Croatia", abbreviation: "HR" }, - { name: "Cuba", abbreviation: "CU" }, - { name: "Curaçao", abbreviation: "CW" }, - { name: "Cyprus", abbreviation: "CY" }, - { name: "Czech Republic", abbreviation: "CZ" }, - { name: "Denmark", abbreviation: "DK" }, - { name: "Diego Garcia", abbreviation: "DG" }, - { name: "Djibouti", abbreviation: "DJ" }, - { name: "Dominica", abbreviation: "DM" }, - { name: "Dominican Republic", abbreviation: "DO" }, - { name: "Ecuador", abbreviation: "EC" }, - { name: "Egypt", abbreviation: "EG" }, - { name: "El Salvador", abbreviation: "SV" }, - { name: "Equatorial Guinea", abbreviation: "GQ" }, - { name: "Eritrea", abbreviation: "ER" }, - { name: "Estonia", abbreviation: "EE" }, - { name: "Ethiopia", abbreviation: "ET" }, - { name: "Falkland Islands", abbreviation: "FK" }, - { name: "Faroe Islands", abbreviation: "FO" }, - { name: "Fiji", abbreviation: "FJ" }, - { name: "Finland", abbreviation: "FI" }, - { name: "France", abbreviation: "FR" }, - { name: "French Guiana", abbreviation: "GF" }, - { name: "French Polynesia", abbreviation: "PF" }, - { name: "French Southern Territories", abbreviation: "TF" }, - { name: "Gabon", abbreviation: "GA" }, - { name: "Gambia", abbreviation: "GM" }, - { name: "Georgia", abbreviation: "GE" }, - { name: "Germany", abbreviation: "DE" }, - { name: "Ghana", abbreviation: "GH" }, - { name: "Gibraltar", abbreviation: "GI" }, - { name: "Greece", abbreviation: "GR" }, - { name: "Greenland", abbreviation: "GL" }, - { name: "Grenada", abbreviation: "GD" }, - { name: "Guadeloupe", abbreviation: "GP" }, - { name: "Guam", abbreviation: "GU" }, - { name: "Guatemala", abbreviation: "GT" }, - { name: "Guernsey", abbreviation: "GG" }, - { name: "Guinea", abbreviation: "GN" }, - { name: "Guinea-Bissau", abbreviation: "GW" }, - { name: "Guyana", abbreviation: "GY" }, - { name: "Haiti", abbreviation: "HT" }, - { name: "Honduras", abbreviation: "HN" }, - { name: "Hong Kong SAR China", abbreviation: "HK" }, - { name: "Hungary", abbreviation: "HU" }, - { name: "Iceland", abbreviation: "IS" }, - { name: "India", abbreviation: "IN" }, - { name: "Indonesia", abbreviation: "ID" }, - { name: "Iran", abbreviation: "IR" }, - { name: "Iraq", abbreviation: "IQ" }, - { name: "Ireland", abbreviation: "IE" }, - { name: "Isle of Man", abbreviation: "IM" }, - { name: "Israel", abbreviation: "IL" }, - { name: "Italy", abbreviation: "IT" }, - { name: "Jamaica", abbreviation: "JM" }, - { name: "Japan", abbreviation: "JP" }, - { name: "Jersey", abbreviation: "JE" }, - { name: "Jordan", abbreviation: "JO" }, - { name: "Kazakhstan", abbreviation: "KZ" }, - { name: "Kenya", abbreviation: "KE" }, - { name: "Kiribati", abbreviation: "KI" }, - { name: "Kosovo", abbreviation: "XK" }, - { name: "Kuwait", abbreviation: "KW" }, - { name: "Kyrgyzstan", abbreviation: "KG" }, - { name: "Laos", abbreviation: "LA" }, - { name: "Latvia", abbreviation: "LV" }, - { name: "Lebanon", abbreviation: "LB" }, - { name: "Lesotho", abbreviation: "LS" }, - { name: "Liberia", abbreviation: "LR" }, - { name: "Libya", abbreviation: "LY" }, - { name: "Liechtenstein", abbreviation: "LI" }, - { name: "Lithuania", abbreviation: "LT" }, - { name: "Luxembourg", abbreviation: "LU" }, - { name: "Macau SAR China", abbreviation: "MO" }, - { name: "Macedonia", abbreviation: "MK" }, - { name: "Madagascar", abbreviation: "MG" }, - { name: "Malawi", abbreviation: "MW" }, - { name: "Malaysia", abbreviation: "MY" }, - { name: "Maldives", abbreviation: "MV" }, - { name: "Mali", abbreviation: "ML" }, - { name: "Malta", abbreviation: "MT" }, - { name: "Marshall Islands", abbreviation: "MH" }, - { name: "Martinique", abbreviation: "MQ" }, - { name: "Mauritania", abbreviation: "MR" }, - { name: "Mauritius", abbreviation: "MU" }, - { name: "Mayotte", abbreviation: "YT" }, - { name: "Mexico", abbreviation: "MX" }, - { name: "Micronesia", abbreviation: "FM" }, - { name: "Moldova", abbreviation: "MD" }, - { name: "Monaco", abbreviation: "MC" }, - { name: "Mongolia", abbreviation: "MN" }, - { name: "Montenegro", abbreviation: "ME" }, - { name: "Montserrat", abbreviation: "MS" }, - { name: "Morocco", abbreviation: "MA" }, - { name: "Mozambique", abbreviation: "MZ" }, - { name: "Myanmar (Burma)", abbreviation: "MM" }, - { name: "Namibia", abbreviation: "NA" }, - { name: "Nauru", abbreviation: "NR" }, - { name: "Nepal", abbreviation: "NP" }, - { name: "Netherlands", abbreviation: "NL" }, - { name: "New Caledonia", abbreviation: "NC" }, - { name: "New Zealand", abbreviation: "NZ" }, - { name: "Nicaragua", abbreviation: "NI" }, - { name: "Niger", abbreviation: "NE" }, - { name: "Nigeria", abbreviation: "NG" }, - { name: "Niue", abbreviation: "NU" }, - { name: "Norfolk Island", abbreviation: "NF" }, - { name: "North Korea", abbreviation: "KP" }, - { name: "Northern Mariana Islands", abbreviation: "MP" }, - { name: "Norway", abbreviation: "NO" }, - { name: "Oman", abbreviation: "OM" }, - { name: "Pakistan", abbreviation: "PK" }, - { name: "Palau", abbreviation: "PW" }, - { name: "Palestinian Territories", abbreviation: "PS" }, - { name: "Panama", abbreviation: "PA" }, - { name: "Papua New Guinea", abbreviation: "PG" }, - { name: "Paraguay", abbreviation: "PY" }, - { name: "Peru", abbreviation: "PE" }, - { name: "Philippines", abbreviation: "PH" }, - { name: "Pitcairn Islands", abbreviation: "PN" }, - { name: "Poland", abbreviation: "PL" }, - { name: "Portugal", abbreviation: "PT" }, - { name: "Puerto Rico", abbreviation: "PR" }, - { name: "Qatar", abbreviation: "QA" }, - { name: "Réunion", abbreviation: "RE" }, - { name: "Romania", abbreviation: "RO" }, - { name: "Russia", abbreviation: "RU" }, - { name: "Rwanda", abbreviation: "RW" }, - { name: "Samoa", abbreviation: "WS" }, - { name: "San Marino", abbreviation: "SM" }, - { name: "São Tomé and Príncipe", abbreviation: "ST" }, - { name: "Saudi Arabia", abbreviation: "SA" }, - { name: "Senegal", abbreviation: "SN" }, - { name: "Serbia", abbreviation: "RS" }, - { name: "Seychelles", abbreviation: "SC" }, - { name: "Sierra Leone", abbreviation: "SL" }, - { name: "Singapore", abbreviation: "SG" }, - { name: "Sint Maarten", abbreviation: "SX" }, - { name: "Slovakia", abbreviation: "SK" }, - { name: "Slovenia", abbreviation: "SI" }, - { name: "Solomon Islands", abbreviation: "SB" }, - { name: "Somalia", abbreviation: "SO" }, - { name: "South Africa", abbreviation: "ZA" }, - { name: "South Georgia & South Sandwich Islands", abbreviation: "GS" }, - { name: "South Korea", abbreviation: "KR" }, - { name: "South Sudan", abbreviation: "SS" }, - { name: "Spain", abbreviation: "ES" }, - { name: "Sri Lanka", abbreviation: "LK" }, - { name: "St. Barthélemy", abbreviation: "BL" }, - { name: "St. Helena", abbreviation: "SH" }, - { name: "St. Kitts & Nevis", abbreviation: "KN" }, - { name: "St. Lucia", abbreviation: "LC" }, - { name: "St. Martin", abbreviation: "MF" }, - { name: "St. Pierre & Miquelon", abbreviation: "PM" }, - { name: "St. Vincent & Grenadines", abbreviation: "VC" }, - { name: "Sudan", abbreviation: "SD" }, - { name: "Suriname", abbreviation: "SR" }, - { name: "Svalbard & Jan Mayen", abbreviation: "SJ" }, - { name: "Swaziland", abbreviation: "SZ" }, - { name: "Sweden", abbreviation: "SE" }, - { name: "Switzerland", abbreviation: "CH" }, - { name: "Syria", abbreviation: "SY" }, - { name: "Taiwan", abbreviation: "TW" }, - { name: "Tajikistan", abbreviation: "TJ" }, - { name: "Tanzania", abbreviation: "TZ" }, - { name: "Thailand", abbreviation: "TH" }, - { name: "Timor-Leste", abbreviation: "TL" }, - { name: "Togo", abbreviation: "TG" }, - { name: "Tokelau", abbreviation: "TK" }, - { name: "Tonga", abbreviation: "TO" }, - { name: "Trinidad & Tobago", abbreviation: "TT" }, - { name: "Tristan da Cunha", abbreviation: "TA" }, - { name: "Tunisia", abbreviation: "TN" }, - { name: "Turkey", abbreviation: "TR" }, - { name: "Turkmenistan", abbreviation: "TM" }, - { name: "Turks & Caicos Islands", abbreviation: "TC" }, - { name: "Tuvalu", abbreviation: "TV" }, - { name: "U.S. Outlying Islands", abbreviation: "UM" }, - { name: "U.S. Virgin Islands", abbreviation: "VI" }, - { name: "Uganda", abbreviation: "UG" }, - { name: "Ukraine", abbreviation: "UA" }, - { name: "United Arab Emirates", abbreviation: "AE" }, - { name: "United Kingdom", abbreviation: "GB" }, - { name: "United States", abbreviation: "US" }, - { name: "Uruguay", abbreviation: "UY" }, - { name: "Uzbekistan", abbreviation: "UZ" }, - { name: "Vanuatu", abbreviation: "VU" }, - { name: "Vatican City", abbreviation: "VA" }, - { name: "Venezuela", abbreviation: "VE" }, - { name: "Vietnam", abbreviation: "VN" }, - { name: "Wallis & Futuna", abbreviation: "WF" }, - { name: "Western Sahara", abbreviation: "EH" }, - { name: "Yemen", abbreviation: "YE" }, - { name: "Zambia", abbreviation: "ZM" }, - { name: "Zimbabwe", abbreviation: "ZW" }, -]; - -const countriesMap = new Map(countries.map((i) => [i.abbreviation, i.name])); - // By passing a number we get a repeatable source of random generation. const main = async () => { const chance = new Chance(1); @@ -293,48 +39,6 @@ const main = async () => { "BACKEND", ]; - const programmingLanguagesAndFrameWorks = [ - "JavaScript", - "PHP", - "Python", - "C++", - "Java", - "C", - "React", - "Drizzle", - "Angular", - "Vue", - "Svelte", - ]; - - const generateCommunityData = (count: number) => { - return Array(count) - .fill(null) - .map(() => { - const country = chance.country(); - const countryFullName = countriesMap.get(country) || "Wakanda"; - const name = `${countryFullName} ${programmingLanguagesAndFrameWorks[chance.integer({ min: 0, max: programmingLanguagesAndFrameWorks.length - 1 })]} Users Group`; - const slug = `${name - .toLowerCase() - .replace(/ /g, "-") - .replace(/[^\w-]+/g, "")}-${nanoid(8)}`; - return { - id: nanoid(8), - name: name, - city: chance.city(), - country: countryFullName, - coverImage: `https://cdn.jsdelivr.net/npm/country-flag-emoji-json@2.0.0/dist/images/${country}.svg`, - description: chance.sentence({ - words: chance.integer({ min: 200, max: 1000 }), - }), - excerpt: chance.sentence({ - words: chance.integer({ min: 10, max: 20 }), - }), - slug, - }; - }); - }; - const randomPosts = (count = 10) => { return Array(count) .fill(null) @@ -412,8 +116,65 @@ ${chance.paragraph()} return users; }; + const seedE2EUser = async () => { + const name = "E2E Test User"; + + const [existingE2EUser] = await db + .selectDistinct() + .from(user) + .where(eq(user.id, E2E_USER_ID)); + + if (existingE2EUser) { + console.log("E2E Test user already exists. Skipping creation"); + return existingE2EUser; + } + + const userData = { + id: E2E_USER_ID, + username: `${name.split(" ").join("-").toLowerCase()}-${chance.integer({ + min: 0, + max: 999, + })}`, + name, + email: E2E_USER_EMAIL, + image: `https://robohash.org/${encodeURIComponent(name)}?bgset=bg1`, + location: chance.country({ full: true }), + bio: chance.sentence({ words: 10 }), + websiteUrl: chance.url(), + }; + const [createdUser] = await db.insert(user).values(userData).returning(); + return createdUser; + }; + + const seedE2EUserSession = async (userId: string) => { + const [existingE2EUserSession] = await db + .selectDistinct() + .from(session) + .where(eq(session.sessionToken, E2E_SESSION_ID)); + + if (existingE2EUserSession) { + console.log("E2E Test session already exists. Skipping creation"); + return existingE2EUserSession; + } + + try { + const currentDate = new Date(); + + return await db + .insert(session) + .values({ + userId, + sessionToken: E2E_SESSION_ID, + // Set session to expire in 6 months. + expires: new Date(currentDate.setMonth(currentDate.getMonth() + 6)), + }) + .returning(); + } catch (err) { + console.log(err); + } + }; + const userData = generateUserData(); - const communityData = generateCommunityData(30); const addUserData = async () => { const tags = sampleTags.map((title) => ({ title })); @@ -488,6 +249,8 @@ ${chance.paragraph()} try { await addUserData(); + const user = await seedE2EUser(); + await seedE2EUserSession(user.id); } catch (error) { console.log("Error:", error); } diff --git a/drizzle/seedE2E.ts b/drizzle/seedE2E.ts deleted file mode 100644 index ec132be4..00000000 --- a/drizzle/seedE2E.ts +++ /dev/null @@ -1,108 +0,0 @@ -import { Chance } from "chance"; -import { user, session } from "../server/db/schema"; -import { eq } from "drizzle-orm"; - -import "dotenv/config"; - -import { drizzle, type PostgresJsDatabase } from "drizzle-orm/postgres-js"; -import postgres from "postgres"; - -const DATABASE_URL = process.env.DATABASE_URL || ""; -const E2E_SESSION_ID = process.env.E2E_USER_SESSION_ID || ""; -const E2E_USER_ID = process.env.E2E_USER_ID || ""; -const E2E_USER_EMAIL = process.env.E2E_USER_EMAIL || ""; - -if (!DATABASE_URL) { - throw new Error("DATABASE_URL is not set"); -} - -if (!E2E_SESSION_ID) { - throw new Error("E2E_SESSION_ID is not set"); -} - -if (!E2E_USER_ID) { - throw new Error("E2E_USER_ID is not set"); -} - -if (!E2E_USER_EMAIL) { - throw new Error("E2E_USER_ID is not set"); -} - -const client = postgres(DATABASE_URL, { max: 1 }); -const db: PostgresJsDatabase = drizzle(client); - -// By passing a number we get a repeatable source of random generation. -const main = async () => { - const chance = new Chance(1); - - const seedE2EUser = async () => { - const name = "E2E Test User"; - - const [existingE2EUser] = await db - .selectDistinct() - .from(user) - .where(eq(user.id, E2E_USER_ID)); - - if (existingE2EUser) { - console.log("E2E Test user already exists. Skipping creation"); - return existingE2EUser; - } - - const userData = { - id: E2E_USER_ID, - username: `${name.split(" ").join("-").toLowerCase()}-${chance.integer({ - min: 0, - max: 999, - })}`, - name, - email: process.env.E2E_USER_EMAIL, - image: `https://robohash.org/${encodeURIComponent(name)}?bgset=bg1`, - location: chance.country({ full: true }), - bio: chance.sentence({ words: 10 }), - websiteUrl: chance.url(), - }; - const [createdUser] = await db.insert(user).values(userData).returning(); - return createdUser; - }; - - const seedE2EUserSession = async (userId: string) => { - const [existingE2EUserSession] = await db - .selectDistinct() - .from(session) - .where(eq(session.sessionToken, E2E_SESSION_ID)); - - if (existingE2EUserSession) { - console.log("E2E Test session already exists. Skipping creation"); - return existingE2EUserSession; - } - - try { - const currentDate = new Date(); - - return await db - .insert(session) - .values({ - userId, - sessionToken: E2E_SESSION_ID, - // Set session to expire in 6 months. - expires: new Date(currentDate.setMonth(currentDate.getMonth() + 6)), - }) - .returning(); - } catch (err) { - console.log(err); - } - }; - - const NODE_ENV = process.env.NODE_ENV; - if (NODE_ENV !== "production") { - const user = await seedE2EUser(); - await seedE2EUserSession(user.id); - console.log(`Succesfully seeded DB with session`); - } else { - console.log( - "This script is only for development, it will delete all of your data.", - ); - } -}; - -main(); diff --git a/e2e/login.spec.ts b/e2e/login.spec.ts index 0cba0ada..491c77c5 100644 --- a/e2e/login.spec.ts +++ b/e2e/login.spec.ts @@ -11,9 +11,7 @@ test.describe("Login Page", () => { await page.context().clearCookies(); await page.goto("http://localhost:3000/get-started"); await page.waitForTimeout(3000); - // const test123 = page.getByTestId("github-login-button"); await expect(page.getByTestId("github-login-button")).toBeVisible(); - // expect(page.getByTestId("github-login-button")).toBeVisible(); }); test("should display the Gitlab login button", async ({ page }) => { diff --git a/playwright.config.ts b/playwright.config.ts index 084a4e4d..91a771e0 100644 --- a/playwright.config.ts +++ b/playwright.config.ts @@ -18,7 +18,7 @@ export default defineConfig({ /* Retry on CI only */ retries: process.env.CI ? 2 : 0, /* Opt out of parallel tests on CI. */ - workers: process.env.CI ? 1 : undefined, + workers: process.env.CI ? 2 : undefined, /* Reporter to use. See https://playwright.dev/docs/test-reporters */ reporter: "html", /* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */