diff --git a/.github/workflows/test-and-publish.yml b/.github/workflows/test-and-publish.yml index 467f6402..bcd47842 100644 --- a/.github/workflows/test-and-publish.yml +++ b/.github/workflows/test-and-publish.yml @@ -28,7 +28,7 @@ jobs: steps: - uses: actions/checkout@v2 - name: Build the docker-compose stack - run: docker-compose up -d + run: docker compose up -d - name: Check running containers run: docker ps - name: Cypress run tests diff --git a/Makefile b/Makefile index 64e6e60f..bcd771cc 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,5 @@ DOCKER_IMAGE?=mentor-admin -TEST_E2E_DOCKER_COMPOSE=docker-compose +TEST_E2E_DOCKER_COMPOSE=docker compose TEST_E2E_IMAGE_SNAPSHOTS_PATH?=cypress/snapshots TEST_E2E_DOCKER_IMAGE_SNAPSHOTS_PATH?=/app/$(TEST_E2E_IMAGE_SNAPSHOTS_PATH) TEST_E2E_HOST_IMAGE_SNAPSHOTS_PATH?=$(PWD)/cypress/$(TEST_E2E_IMAGE_SNAPSHOTS_PATH) diff --git a/client/Makefile b/client/Makefile index e387858d..062e7d51 100644 --- a/client/Makefile +++ b/client/Makefile @@ -4,7 +4,7 @@ clean: .PHONY: develop develop: node_modules/gatsby - npx gatsby develop -p 80 + npx gatsby develop -p 8000 .PHONY: pretty pretty: diff --git a/client/src/components/config/mentor-list.tsx b/client/src/components/config/mentor-list.tsx index 34b126ff..32d6982d 100644 --- a/client/src/components/config/mentor-list.tsx +++ b/client/src/components/config/mentor-list.tsx @@ -118,7 +118,7 @@ function MentorItem(props: { launchMentor( diff --git a/client/src/components/config/mentor-panel-item.tsx b/client/src/components/config/mentor-panel-item.tsx index b355376a..f0d7a0e1 100644 --- a/client/src/components/config/mentor-panel-item.tsx +++ b/client/src/components/config/mentor-panel-item.tsx @@ -109,7 +109,7 @@ export function MentorPanelItem(props: { launchMentorPanel( diff --git a/client/src/components/home/index.tsx b/client/src/components/home/index.tsx index 055b59cb..26654a57 100644 --- a/client/src/components/home/index.tsx +++ b/client/src/components/home/index.tsx @@ -35,7 +35,7 @@ import parseMentor, { defaultMentorInfo, } from "components/my-mentor-card/mentor-info"; import NavBar from "components/nav-bar"; -import { canEditContent, launchMentor } from "helpers"; +import { canEditContent, isAdmin, launchMentor } from "helpers"; import { QuestionEdits, useWithReviewAnswerState, @@ -57,6 +57,7 @@ import { trainMentor } from "api"; import { useWithConfig } from "store/slices/config/useWithConfig"; import { BuildMentorTooltip } from "./build-mentor-tooltip"; import { MentorConfig } from "types-gql"; +import { useAppSelector } from "store/hooks"; const useStyles = makeStyles({ name: { HomePage } })((theme: Theme) => ({ toolbar: { @@ -155,7 +156,9 @@ function HomePage(props: { const mentorConfig: MentorConfig | undefined = getData( (m) => m.data?.mentorConfig ); - const lockedToConfig: boolean = getData((m) => m.data?.lockedToConfig); + const user = useAppSelector((state) => state.login.user); + const lockedToConfig: boolean = + !isAdmin(user) && getData((m) => m.data?.lockedToConfig); const defaultMentor = props.user.defaultMentor._id; const { classes } = useStyles(); const [showSetupAlert, setShowSetupAlert] = useState(true); @@ -532,7 +535,7 @@ function HomePage(props: { {name} ))} - {mentorConfig?.lockedToSubjects ? undefined : ( + {lockedToConfig && mentorConfig?.lockedToSubjects ? undefined : ( ({ toolbar: { @@ -320,7 +321,8 @@ export function NavBar(props: { } = props; const { getData } = useActiveMentor(); const mentor: Mentor | undefined = getData((state) => state.data); - + const user = useAppSelector((state) => state.login.user); + const lockedToConfig = mentor?.lockedToConfig && !isAdmin(user); const importStatus = useWithImportStatus(); const { importTask } = importStatus; const numUploadsInProgress = @@ -403,7 +405,9 @@ export function NavBar(props: { > state.login.user); const mentor: Mentor = getData((state) => state.data); useQuestions( @@ -194,11 +200,16 @@ export function useWithSetup( requiredSubjects, isSetupComplete, }); - const mentorSubjectsLocked = mentor.mentorConfig?.lockedToSubjects; + const lockedToConfig = !isAdmin(user) && mentor.lockedToConfig; + const mentorSubjectsLocked = + lockedToConfig && mentor.mentorConfig?.lockedToSubjects; const mentorPrivacyLocked = - mentor.mentorConfig?.publiclyVisible !== undefined || - mentor.mentorConfig?.orgPermissions.length; - const mentorTypeLocked = mentor.mentorConfig?.mentorType; + lockedToConfig && + (mentor.mentorConfig?.publiclyVisible !== undefined || + mentor.mentorConfig?.orgPermissions.length); + const mentorTypeLocked = lockedToConfig && mentor.mentorConfig?.mentorType; + const disabledMyGoalSlide = + lockedToConfig && mentor.mentorConfig?.disableMyGoalSlide; const status: SetupStep[] = [ { type: SetupStepType.WELCOME, complete: true }, { type: SetupStepType.MENTOR_INFO, complete: isMentorInfoDone }, @@ -208,7 +219,7 @@ export function useWithSetup( ...(mentorPrivacyLocked ? [] : [{ type: SetupStepType.MENTOR_PRIVACY, complete: true }]), - ...(mentor.mentorConfig?.disableMyGoalSlide + ...(disabledMyGoalSlide ? [] : [ { type: SetupStepType.MENTOR_GOAL, complete: Boolean(mentor.goal) }, diff --git a/cypress/cypress.config.ts b/cypress/cypress.config.ts index 38a88606..6e8470d3 100644 --- a/cypress/cypress.config.ts +++ b/cypress/cypress.config.ts @@ -16,6 +16,6 @@ export default defineConfig({ setupNodeEvents(on, config) { return require("./cypress/plugins/index.ts")(on, config); }, - baseUrl: "http://localhost:80", + baseUrl: "http://localhost:8000", }, }); diff --git a/cypress/cypress/e2e/config.cy.ts b/cypress/cypress/e2e/config.cy.ts index 5c036e7d..ba1c3eb9 100644 --- a/cypress/cypress/e2e/config.cy.ts +++ b/cypress/cypress/e2e/config.cy.ts @@ -261,7 +261,9 @@ describe("config screen", () => { cy.get('[data-cy=toggle-active] [type="checkbox"]').should( "be.checked" ); - cy.get("[data-cy=launch-mentor]").trigger("mouseover").click(); + cy.get("[data-cy=launch-mentor-62aa503082f27ce347bdc7f4]") + .should("exist") + .should("be.enabled"); }); }); }); @@ -323,7 +325,9 @@ describe("config screen", () => { cy.get('[data-cy=toggle-featured] [type="checkbox"]').should( "not.be.checked" ); - cy.get("[data-cy=launch-mentor]").trigger("mouseover").click(); + cy.get("[data-cy=launch-mentor-62b4f62482f27ce347ba02e2]") + .should("exist") + .should("be.enabled"); }); }); }); @@ -381,7 +385,11 @@ describe("config screen", () => { cy.get('[data-cy=toggle-active] [type="checkbox"]').should( "be.checked" ); - cy.get("[data-cy=launch-mentor-panel]").trigger("mouseover").click(); + cy.get( + "[data-cy=launch-mentor-panel-62b4f62482f27ce347ba02e2-62aa503082f27ce347bdc7f4-62aa503082f27ce347bdc7f8]" + ) + .should("exist") + .should("be.enabled"); }); }); }); @@ -434,7 +442,11 @@ describe("config screen", () => { cy.get('[data-cy=toggle-featured] [type="checkbox"]').should( "not.be.checked" ); - cy.get("[data-cy=launch-mentor-panel]").trigger("mouseover").click(); + cy.get( + "[data-cy=launch-mentor-panel-62b4f62482f27ce347ba02e2-62aa503082f27ce347bdc7f4-62aa503082f27ce347bdc7f8]" + ) + .should("exist") + .should("be.enabled"); }); }); }); diff --git a/cypress/cypress/e2e/home.cy.ts b/cypress/cypress/e2e/home.cy.ts index 4388d31b..3a30c79d 100644 --- a/cypress/cypress/e2e/home.cy.ts +++ b/cypress/cypress/e2e/home.cy.ts @@ -1186,6 +1186,7 @@ describe("My Mentor Page", () => { cyMockDefault(cy, { mentor: { ...clintWithConfig, + lockedToConfig: true, mentorConfig: { ...clintWithConfig.mentorConfig, lockedToSubjects: true, @@ -1203,6 +1204,7 @@ describe("My Mentor Page", () => { cyMockDefault(cy, { mentor: { ...clintWithConfig, + lockedToConfig: true, mentorConfig: { ...clintWithConfig.mentorConfig, lockedToSubjects: true, diff --git a/cypress/cypress/e2e/setup.cy.ts b/cypress/cypress/e2e/setup.cy.ts index 4847f9f5..a5e59d3d 100644 --- a/cypress/cypress/e2e/setup.cy.ts +++ b/cypress/cypress/e2e/setup.cy.ts @@ -1292,10 +1292,7 @@ describe("Setup", () => { .get("[data-cy=nav-btn-avatar]") .should("have.css", "backgroundColor", "rgb(255, 0, 0)"); cy.contains("1 / 3"); - cy.getSettled("[data-cy=record-btn]", { retries: 4 }) - .trigger("mouseover") - .click(); - // go to record + cy.getSettled("[data-cy=record-btn]", { delay: 1000 }).click(); cy.location("pathname").then(($el) => assert($el.replace("/admin", ""), "/record") ); @@ -1446,6 +1443,7 @@ describe("Setup", () => { it("Record required subject slide considers answer as complete if upload in progress", () => { const videoWithConfigAndUnansweredQ: Mentor = { ...completeMentor(videoMentor), + lockedToConfig: true, mentorConfig: mentorConfig, name: "helo", firstName: "world", diff --git a/cypress/cypress/fixtures/recording/video_mentors.ts b/cypress/cypress/fixtures/recording/video_mentors.ts index 15022eb6..b9c6ea9b 100644 --- a/cypress/cypress/fixtures/recording/video_mentors.ts +++ b/cypress/cypress/fixtures/recording/video_mentors.ts @@ -217,5 +217,6 @@ export const mentorConfig: MentorConfig = { }; export const videoMentorWithConfig: Mentor = { ...videoMentor, + lockedToConfig: true, mentorConfig, }; diff --git a/cypress/cypress/support/types.ts b/cypress/cypress/support/types.ts index ead280b8..85d87d4c 100644 --- a/cypress/cypress/support/types.ts +++ b/cypress/cypress/support/types.ts @@ -128,6 +128,7 @@ export interface Mentor { isPrivate: boolean; isArchived: boolean; isAdvanced: boolean; + lockedToConfig?: boolean; defaultSubject?: Subject; mentorConfig?: MentorConfig; numAnswersComplete: number;