diff --git a/frontend/src/API.ts b/frontend/src/API.ts index 11ab47a29..4ca97f79a 100644 --- a/frontend/src/API.ts +++ b/frontend/src/API.ts @@ -61,19 +61,19 @@ export const useConsent = (slug: string) => useGet(API_BASE_URL + URLS.result.get('consent_' + slug)); interface CreateConsentParams { - experiment: Block; + block: Block; participant: Participant; } -// Create consent for given experiment -export const createConsent = async ({ experiment, participant }: CreateConsentParams) => { +/** Create consent for given experiment */ +export const createConsent = async ({ block, participant }: CreateConsentParams) => { try { const response = await axios.post( API_BASE_URL + URLS.result.consent, qs.stringify({ json_data: JSON.stringify( { - key: "consent_" + experiment.slug, + key: "consent_" + block.slug, value: true, } ), @@ -88,18 +88,18 @@ export const createConsent = async ({ experiment, participant }: CreateConsentPa }; interface CreateSessionParams { - experiment: Block; + block: Block; participant: Participant; playlist: { current: string }; } // Create a new session for given experiment -export const createSession = async ({experiment, participant, playlist}: CreateSessionParams) => { +export const createSession = async ({ block, participant, playlist }: CreateSessionParams) => { try { const response = await axios.post( API_BASE_URL + URLS.session.create, qs.stringify({ - experiment_id: experiment.id, + experiment_id: block.id, playlist_id: playlist.current, csrfmiddlewaretoken: participant.csrf_token, }) @@ -186,7 +186,7 @@ export const scoreIntermediateResult = async ({ interface GetNextRoundParams { session: Session; } - + // Get next_round from server export const getNextRound = async ({ session }: GetNextRoundParams) => { @@ -249,14 +249,14 @@ export const shareParticipant = async ({ email, participant }: ShareParticipantP }; interface PostFeedbackParams { - experimentSlug: string; + blockSlug: string; feedback: string; participant: Participant; } // Collect user feedback -export const postFeedback = async({ experimentSlug, feedback, participant }: PostFeedbackParams) => { - const endpoint = API_BASE_URL + URLS.block.feedback(experimentSlug) +export const postFeedback = async ({ blockSlug, feedback, participant }: PostFeedbackParams) => { + const endpoint = API_BASE_URL + URLS.block.feedback(blockSlug) try { const response = await axios.post( endpoint, diff --git a/frontend/src/components/Block/Block.jsx b/frontend/src/components/Block/Block.jsx index 68c9ff1f0..3398657af 100644 --- a/frontend/src/components/Block/Block.jsx +++ b/frontend/src/components/Block/Block.jsx @@ -70,7 +70,7 @@ const Block = ({ match }) => { return session; } try { - const newSession = await createSession({ experiment: block, participant, playlist }) + const newSession = await createSession({ block, participant, playlist }) setSession(newSession); return newSession; } @@ -165,7 +165,7 @@ const Block = ({ match }) => { const render = (view) => { // Default attributes for every view const attrs = { - experiment: block, + block, participant, loadingText, onResult, @@ -260,7 +260,7 @@ const Block = ({ match }) => { {block?.feedback_info?.show_float_button && ( diff --git a/frontend/src/components/Consent/Consent.jsx b/frontend/src/components/Consent/Consent.jsx index eb237159b..da7641749 100644 --- a/frontend/src/components/Consent/Consent.jsx +++ b/frontend/src/components/Consent/Consent.jsx @@ -7,9 +7,9 @@ import Loading from "../Loading/Loading"; import { createConsent, useConsent } from "../../API"; import classNames from "classnames"; -// Consent is an experiment view that shows the consent text, and handles agreement/stop actions -const Consent = ({ title, text, experiment, participant, onNext, confirm, deny }) => { - const [consent, loadingConsent] = useConsent(experiment.slug); +/** Consent is an block view that shows the consent text, and handles agreement/stop actions */ +const Consent = ({ title, text, block, participant, onNext, confirm, deny }) => { + const [consent, loadingConsent] = useConsent(block.slug); const urlQueryString = window.location.search; // Listen for consent, and auto advance if already given @@ -22,7 +22,7 @@ const Consent = ({ title, text, experiment, participant, onNext, confirm, deny } // Click on agree button const onAgree = async () => { // Store consent - await createConsent({ experiment, participant }); + await createConsent({ block, participant }); // Next! onNext(); @@ -31,14 +31,14 @@ const Consent = ({ title, text, experiment, participant, onNext, confirm, deny } const onDownload = async () => { const doc = new DOMParser().parseFromString(text, 'text/html'); const txt = doc.body.textContent.split(' ').join(''); - const blob = new Blob([txt], {type: "text/plain;charset=utf-8"}); + const blob = new Blob([txt], { type: "text/plain;charset=utf-8" }); saveAs(blob, 'consent.txt'); } // Loader in case consent is being loaded // or it was already given if (loadingConsent || consent) { - return ; + return ; } // Calculate height for consent text to prevent overlapping browser chrome diff --git a/frontend/src/components/Consent/Consent.test.jsx b/frontend/src/components/Consent/Consent.test.jsx index cf35b90e2..c9686611e 100644 --- a/frontend/src/components/Consent/Consent.test.jsx +++ b/frontend/src/components/Consent/Consent.test.jsx @@ -29,20 +29,20 @@ const mockBlock = { describe('Consent', () => { it('renders loading state correctly', () => { useConsent.mockReturnValue([null, true]); // Mock loading state - const { getByText } = render(); + const { getByText } = render(); expect(document.body.contains(getByText('Loading...'))).to.be.true; }); it('renders consent text when not loading', () => { useConsent.mockReturnValue([null, false]); - const { getByText } = render(); + const { getByText } = render(); expect(document.body.contains(getByText('Consent Text'))).to.be.true; }); it('calls onNext when Agree button is clicked', async () => { useConsent.mockReturnValue([null, false]); const onNext = vi.fn(); - const { getByText } = render(); + const { getByText } = render(); fireEvent.click(getByText('Agree')); await waitFor(() => expect(onNext).toHaveBeenCalled()); @@ -50,7 +50,7 @@ describe('Consent', () => { it('triggers download when Download button is clicked', async () => { useConsent.mockReturnValue([null, false]); - const { getByTestId } = render(); + const { getByTestId } = render(); fireEvent.click(getByTestId('download-button')); await waitFor(() => expect(saveAs).toHaveBeenCalled()); @@ -59,14 +59,14 @@ describe('Consent', () => { it('auto advances if consent is already given', () => { useConsent.mockReturnValue([true, false]); const onNext = vi.fn(); - render(); + render(); expect(onNext).toHaveBeenCalled(); }); it('calculates style for consent text correctly', () => { useConsent.mockReturnValue([null, false]); Object.defineProperty(window, 'innerHeight', { writable: true, configurable: true, value: 800 }); - const { getByTestId } = render(); + const { getByTestId } = render(); const consentText = getByTestId('consent-text'); expect(consentText.style.height).toBe('500px'); }); diff --git a/frontend/src/components/ExperimentCollection/ExperimentCollection.test.tsx b/frontend/src/components/ExperimentCollection/ExperimentCollection.test.tsx index 4cae6f49b..78df22019 100644 --- a/frontend/src/components/ExperimentCollection/ExperimentCollection.test.tsx +++ b/frontend/src/components/ExperimentCollection/ExperimentCollection.test.tsx @@ -7,17 +7,17 @@ import axios from 'axios'; import ExperimentCollection from './ExperimentCollection'; let mock = new MockAdapter(axios); -const getExperiment = (overrides = {}) => { +const getBlock = (overrides = {}) => { return { slug: 'some_slug', - name: 'Some Experiment', + name: 'Some Block', ...overrides }; } -const experiment1 = getExperiment({ +const block1 = getBlock({ slug: 'some_slug', - name: 'Some Experiment' + name: 'Some Block' }); const theme = { @@ -48,27 +48,27 @@ const theme = { } } -const experimentWithAllProps = getExperiment({ image: 'some_image.jpg', description: 'Some description' }); +const blockWithAllProps = getBlock({ image: 'some_image.jpg', description: 'Some description' }); describe('ExperimentCollection', () => { - it('forwards to a single experiment if it receives an empty dashboard array', async () => { - mock.onGet().replyOnce(200, {dashboard: [], nextExperiment: experiment1}); + it('forwards to a single block if it receives an empty dashboard array', async () => { + mock.onGet().replyOnce(200, { dashboard: [], nextExperiment: block1 }); render( - - - ); + + + ); await waitFor(() => { expect(screen.queryByRole('menu')).toBeFalsy(); }) }); it('shows a loading spinner while loading', () => { - mock.onGet().replyOnce(200, new Promise(() => {})); + mock.onGet().replyOnce(200, new Promise(() => { })); render( - - - + + + ); waitFor(() => { expect(document.querySelector('.loader-container')).not.toBeNull(); @@ -76,11 +76,11 @@ describe('ExperimentCollection', () => { }); it('shows a placeholder if no image is available', () => { - mock.onGet().replyOnce(200, { dashboard: [experiment1], nextExperiment: experiment1 }); + mock.onGet().replyOnce(200, { dashboard: [block1], nextExperiment: block1 }); render( - - - + + + ); waitFor(() => { expect(document.querySelector('.loader-container')).not.toBeNull(); @@ -88,11 +88,11 @@ describe('ExperimentCollection', () => { }); it('shows the image if it is available', () => { - mock.onGet().replyOnce(200, { dashboard: [experimentWithAllProps], nextExperiment: experiment1 }); + mock.onGet().replyOnce(200, { dashboard: [blockWithAllProps], nextExperiment: block1 }); render( - - - + + + ); waitFor(() => { expect(document.querySelector('img')).not.toBeNull(); @@ -100,11 +100,11 @@ describe('ExperimentCollection', () => { }); it('shows the description if it is available', () => { - mock.onGet().replyOnce(200, { dashboard: [experimentWithAllProps], nextExperiment: experiment1 }); + mock.onGet().replyOnce(200, { dashboard: [blockWithAllProps], nextExperiment: block1 }); render( - - - + + + ); waitFor(() => { expect(screen.getByText('Some description')).toBeInTheDocument(); @@ -112,10 +112,10 @@ describe('ExperimentCollection', () => { }); it('shows consent first if available', async () => { - mock.onGet().replyOnce(200, { consent: '

This is our consent form!

', dashboard: [experimentWithAllProps], nextExperiment: experiment1} ); + mock.onGet().replyOnce(200, { consent: '

This is our consent form!

', dashboard: [blockWithAllProps], nextExperiment: block1 }); render( - + ); await waitFor(() => { @@ -124,14 +124,14 @@ describe('ExperimentCollection', () => { }); it('shows a footer if a theme with footer is available', async () => { - mock.onGet().replyOnce(200, { dashboard: [experimentWithAllProps], nextExperiment: experiment1, theme }); + mock.onGet().replyOnce(200, { dashboard: [blockWithAllProps], nextExperiment: block1, theme }); render( - + ); - await waitFor( () => { + await waitFor(() => { expect(document.querySelector('.aha__footer')).not.toBeNull(); }) }) -}) \ No newline at end of file +}) diff --git a/frontend/src/components/ExperimentCollection/ExperimentCollection.tsx b/frontend/src/components/ExperimentCollection/ExperimentCollection.tsx index f95ba2123..885aee954 100644 --- a/frontend/src/components/ExperimentCollection/ExperimentCollection.tsx +++ b/frontend/src/components/ExperimentCollection/ExperimentCollection.tsx @@ -64,12 +64,12 @@ const ExperimentCollection = ({ match }: ExperimentCollectionProps) => { const attrs = { participant, onNext, - experiment: experimentCollection, + block: experimentCollection, ...experimentCollection.consent, } return ( - + ) } @@ -95,4 +95,4 @@ const ExperimentCollection = ({ match }: ExperimentCollectionProps) => { ) } -export default ExperimentCollection; \ No newline at end of file +export default ExperimentCollection; diff --git a/frontend/src/components/ExperimentCollection/ExperimentCollectionDashboard/ExperimentCollectionDashboard.tsx b/frontend/src/components/ExperimentCollection/ExperimentCollectionDashboard/ExperimentCollectionDashboard.tsx index e31437177..6b9318fc7 100644 --- a/frontend/src/components/ExperimentCollection/ExperimentCollectionDashboard/ExperimentCollectionDashboard.tsx +++ b/frontend/src/components/ExperimentCollection/ExperimentCollectionDashboard/ExperimentCollectionDashboard.tsx @@ -16,10 +16,10 @@ interface ExperimentCollectionDashboardProps { export const ExperimentCollectionDashboard: React.FC = ({ experimentCollection, participantIdUrl, totalScore }) => { const dashboard = experimentCollection.dashboard; - const nextExperimentSlug = experimentCollection.nextExperiment?.slug; + const nextBlockSlug = experimentCollection.nextExperiment?.slug; const headerProps = experimentCollection.theme?.header ? { - nextExperimentSlug, + nextBlockSlug, collectionSlug: experimentCollection.slug, ...experimentCollection.theme.header, totalScore, diff --git a/frontend/src/components/Explainer/Explainer.jsx b/frontend/src/components/Explainer/Explainer.jsx index bd24d8c1c..1ed671b14 100644 --- a/frontend/src/components/Explainer/Explainer.jsx +++ b/frontend/src/components/Explainer/Explainer.jsx @@ -1,14 +1,17 @@ -import React, {useEffect} from "react"; +import React, { useEffect } from "react"; import Button from "../Button/Button"; -// Explainer is an experiment view that shows a list of steps -// If the button has not been clicked, onNext will be called automatically after the timer expires (in milliseconds). If timer == null, onNext will only be called after the button is clicked. +/** + * Explainer is an block view that shows a list of steps + * If the button has not been clicked, onNext will be called automatically after the timer expires (in milliseconds). + * If timer == null, onNext will only be called after the button is clicked. + */ const Explainer = ({ instruction, button_label, steps = [], timer = null, onNext }) => { - useEffect( () => { + useEffect(() => { if (timer != null) { const id = setTimeout(onNext, timer); - return () => {clearTimeout(id)}; // if button has been clicked, clear timeout + return () => { clearTimeout(id) }; // if button has been clicked, clear timeout } }, [onNext, timer]) diff --git a/frontend/src/components/Final/Final.jsx b/frontend/src/components/Final/Final.jsx index 43996aa11..b4a811333 100644 --- a/frontend/src/components/Final/Final.jsx +++ b/frontend/src/components/Final/Final.jsx @@ -11,9 +11,11 @@ import ParticipantLink from "../ParticipantLink/ParticipantLink"; import UserFeedback from "../UserFeedback/UserFeedback"; import FinalButton from "./FinalButton"; -// Final is an experiment view that shows the final scores of the experiment -// It can only be the last view of an experiment -const Final = ({ experiment, participant, score, final_text, action_texts, button, +/** + * Final is an block view that shows the final scores of the block + * It can only be the last view of a block + */ +const Final = ({ block, participant, score, final_text, action_texts, button, onNext, history, show_participant_link, participant_id_only, show_profile_link, social, feedback_info, points, rank, logo }) => { const [showScore, setShowScore] = useState(0); @@ -103,7 +105,7 @@ const Final = ({ experiment, participant, score, final_text, action_texts, butto /> )} {feedback_info && ()} diff --git a/frontend/src/components/Final/Final.test.jsx b/frontend/src/components/Final/Final.test.jsx index 4368ddf65..33c2876d8 100644 --- a/frontend/src/components/Final/Final.test.jsx +++ b/frontend/src/components/Final/Final.test.jsx @@ -15,7 +15,7 @@ vi.mock('../../util/stores', () => ({ session: 1, participant: 'participant-id', }; - + return fn(state); }, useBoundStore: vi.fn() @@ -43,7 +43,7 @@ describe('Final Component', () => { render( { ); diff --git a/frontend/src/components/Header/Header.tsx b/frontend/src/components/Header/Header.tsx index e2d7fd9b5..d2a980253 100644 --- a/frontend/src/components/Header/Header.tsx +++ b/frontend/src/components/Header/Header.tsx @@ -8,7 +8,7 @@ import HTML from '@/components/HTML/HTML'; interface HeaderProps { experimentCollectionTitle: string; experimentCollectionDescription: string; - nextExperimentSlug: string | undefined; + nextBlockSlug: string | undefined; nextExperimentButtonText: string; collectionSlug: string; aboutButtonText: string; @@ -24,7 +24,7 @@ interface Score { export const Header: React.FC = ({ experimentCollectionTitle, experimentCollectionDescription, - nextExperimentSlug, + nextBlockSlug, nextExperimentButtonText, collectionSlug, aboutButtonText, @@ -104,7 +104,7 @@ export const Header: React.FC = ({
diff --git a/frontend/src/components/Info/Info.jsx b/frontend/src/components/Info/Info.jsx index 187f076ec..1ef375f0c 100644 --- a/frontend/src/components/Info/Info.jsx +++ b/frontend/src/components/Info/Info.jsx @@ -2,7 +2,7 @@ import React, { useEffect, useState } from "react"; import Button from "../Button/Button"; -// Info is an experiment view that shows the Info text, and handles agreement/stop actions +/** Info is an block view that shows the Info text, and handles agreement/stop actions */ const Info = ({ heading, body, button_label, button_link, onNext }) => { const [maxHeight, setMaxHeight] = useState(getMaxHeight()); diff --git a/frontend/src/components/Loading/Loading.jsx b/frontend/src/components/Loading/Loading.jsx index 90b03eb36..0d57ec8af 100644 --- a/frontend/src/components/Loading/Loading.jsx +++ b/frontend/src/components/Loading/Loading.jsx @@ -2,8 +2,10 @@ import React from "react"; import Circle from "../Circle/Circle"; -// Loading is an experiment view that shows a loading screen -// - It is normally set by code during loading of data +/** + * Loading is an experiment view that shows a loading screen + * It is normally set by code during loading of data + */ const Loading = ({ duration = 2, loadingText }) => { return (
diff --git a/frontend/src/components/Page/DefaultPage.test.jsx b/frontend/src/components/Page/DefaultPage.test.jsx index 6b815cf0f..2bc4883ae 100644 --- a/frontend/src/components/Page/DefaultPage.test.jsx +++ b/frontend/src/components/Page/DefaultPage.test.jsx @@ -17,20 +17,20 @@ describe("DefaultPage Component Tests", () => { } const defaultProps = { - className:'aha__default', + className: 'aha__default', title: "Default page title", logoClickConfirm: null, collectionSlug: 'some_collection', - nextExperimentSlug: 'some_experiment', + nextBlockSlug: 'some_experiment', } it('renders itself with children', async () => { render( - - + + ) await screen.findByText('Some instruction'); }) - -}); \ No newline at end of file + +}); diff --git a/frontend/src/components/Playlist/Playlist.jsx b/frontend/src/components/Playlist/Playlist.jsx index 064db59da..0c4746439 100644 --- a/frontend/src/components/Playlist/Playlist.jsx +++ b/frontend/src/components/Playlist/Playlist.jsx @@ -1,8 +1,10 @@ import React, { useEffect } from "react"; -// Playlist is an experiment view, that handles (auto)selection of a playlist -const Playlist = ({ experiment, instruction, onNext, playlist }) => { - const playlists = experiment.playlists; +/** + * Playlist is an block view, that handles (auto)selection of a playlist + */ +const Playlist = ({ block, instruction, onNext, playlist }) => { + const playlists = block.playlists; useEffect(() => { if (playlists.length < 2) { diff --git a/frontend/src/components/Playlist/Playlist.test.jsx b/frontend/src/components/Playlist/Playlist.test.jsx index 02e85a234..894ef7377 100644 --- a/frontend/src/components/Playlist/Playlist.test.jsx +++ b/frontend/src/components/Playlist/Playlist.test.jsx @@ -8,12 +8,12 @@ vi.mock("../../util/stores"); describe('Playlist Component', () => { const playlist = { current: 25 }; - const experimentProp = { slug: 'test-experiment', playlists: [{id: 42}, {id: 43}] }; + const block = { slug: 'test-experiment', playlists: [{ id: 42 }, { id: 43 }] }; const onNext = vi.fn(); it('renders correctly with given props', () => { render( - + ) expect(screen.getByTestId('playlist-instruction')).to.exist; const playlistItems = screen.getAllByTestId('playlist-item'); @@ -22,18 +22,18 @@ describe('Playlist Component', () => { it('calls onNext when playlist item is clicked', () => { render( - + ) fireEvent.click(screen.getAllByTestId('playlist-item')[0]); expect((onNext).toHaveBeenCalled); }) it('does not render with less than 2 playlists', () => { - experimentProp.playlists = [{id: 42}] + block.playlists = [{ id: 42 }] render( - + ) expect((onNext).toHaveBeenCalled); expect(screen.queryByTestId('playlist-instruction')).not.to.exist; }); -}); \ No newline at end of file +}); diff --git a/frontend/src/components/Score/Score.jsx b/frontend/src/components/Score/Score.jsx index 30128c926..29223ddf4 100644 --- a/frontend/src/components/Score/Score.jsx +++ b/frontend/src/components/Score/Score.jsx @@ -3,7 +3,7 @@ import classNames from "classnames"; import Circle from "../Circle/Circle"; import Button from "../Button/Button"; -// Score is an experiment view that shows an intermediate and total score +/** Score is an block view that shows an intermediate and total score */ const Score = ({ last_song, score, @@ -21,7 +21,7 @@ const Score = ({ const scoreValue = useRef(0); useEffect(() => { - + const id = setTimeout(() => { // Score step const scoreStep = Math.max( @@ -57,7 +57,7 @@ const Score = ({ } }; }, [timer, onNext]); - + return (
- + {total_score !== undefined && (

{texts.score}: {total_score - score + showScore}

- )} + )} {!timer && (
diff --git a/frontend/src/components/ToontjeHoger/ToontjeHoger.jsx b/frontend/src/components/ToontjeHoger/ToontjeHoger.jsx index 00712c216..38986c881 100644 --- a/frontend/src/components/ToontjeHoger/ToontjeHoger.jsx +++ b/frontend/src/components/ToontjeHoger/ToontjeHoger.jsx @@ -162,11 +162,11 @@ const Privacy = ({ description }) => (
); -// ToontjeHoger is an experiment view that shows the ToontjeHoger home -const ToontjeHogerHome = ({ experiment, config, experiments }) => { +/** ToontjeHoger is an block view that shows the ToontjeHoger home */ +const ToontjeHogerHome = ({ block, config, experiments }) => { return (
- + {/* Hero */}
@@ -182,7 +182,7 @@ const ToontjeHogerHome = ({ experiment, config, experiments }) => { {config.intro_read_more && ( {config.intro_read_more} @@ -240,11 +240,11 @@ const ToontjeHogerHome = ({ experiment, config, experiments }) => { ); }; -// ToontjeHoger is an experiment view that shows the ToontjeHoger home -const ToontjeHogerAbout = ({ experiment, config, experiments }) => { +/** ToontjeHoger is an block view that shows the ToontjeHoger home */ +const ToontjeHogerAbout = ({ block, config }) => { return (
- + {/* Project */}

{config.intro_read_more}

@@ -306,10 +306,10 @@ const ToontjeHogerAbout = ({ experiment, config, experiments }) => { }; const ToontjeHoger = (props) => { - return props.experiment ? ( + return props.block ? ( <> - + diff --git a/frontend/src/components/Trial/Trial.jsx b/frontend/src/components/Trial/Trial.jsx index f78e290c0..8d656e73b 100644 --- a/frontend/src/components/Trial/Trial.jsx +++ b/frontend/src/components/Trial/Trial.jsx @@ -7,11 +7,12 @@ import HTML from "../HTML/HTML"; import Playback from "../Playback/Playback"; import Button from "../Button/Button"; -/** Trial is an experiment view to present information to the user and/or collect user feedback -If "playback" is provided, it will play audio through the Playback component -If "html" is provided, it will show html content -If "feedback_form" is provided, it will present a form of questions to the user -**/ +/** + * Trial is an block view to present information to the user and/or collect user feedback + * If "playback" is provided, it will play audio through the Playback component + * If "html" is provided, it will show html content + * If "feedback_form" is provided, it will present a form of questions to the user + */ const Trial = ({ playback, html, diff --git a/frontend/src/components/UserFeedback/UserFeedback.jsx b/frontend/src/components/UserFeedback/UserFeedback.jsx index ae982debd..b5bd6394e 100644 --- a/frontend/src/components/UserFeedback/UserFeedback.jsx +++ b/frontend/src/components/UserFeedback/UserFeedback.jsx @@ -1,17 +1,17 @@ -import React, { useState} from 'react'; +import React, { useState } from 'react'; import { postFeedback } from '../../API'; import Button from '../Button/Button'; import HTML from '../HTML/HTML'; import classNames from '@/util/classNames'; -const UserFeedback = ({experimentSlug, participant, feedbackInfo, inline = true}) => { +const UserFeedback = ({ blockSlug, participant, feedbackInfo, inline = true }) => { const [value, setValue] = useState(''); const [showForm, setShowForm] = useState(true); const giveFeedback = async () => { const data = { - experimentSlug: experimentSlug, + blockSlug, feedback: value, participant } @@ -28,26 +28,27 @@ const UserFeedback = ({experimentSlug, participant, feedbackInfo, inline = true} return (
- {showForm === true ? ( -
-
{feedbackInfo.header}
-
- -
+
- -
- ) : (

{feedbackInfo.thank_you}

)} + ) : (

{feedbackInfo.thank_you}

)}
-)}; + ) +}; export default UserFeedback; diff --git a/frontend/src/components/UserFeedback/UserFeedback.test.jsx b/frontend/src/components/UserFeedback/UserFeedback.test.jsx index 826b12294..f150524a6 100644 --- a/frontend/src/components/UserFeedback/UserFeedback.test.jsx +++ b/frontend/src/components/UserFeedback/UserFeedback.test.jsx @@ -6,70 +6,70 @@ import { postFeedback } from '../../API'; // Mock the API call vi.mock('../../API', () => ({ - postFeedback: vi.fn(), + postFeedback: vi.fn(), })); describe('UserFeedback', () => { - const mockExperimentSlug = 'test-slug'; - const mockParticipant = { id: 1 }; - const mockFeedbackInfo = { - header: 'Your Feedback', - button: 'Submit', - contact_body: 'Contact us at test@example.com', - thank_you: 'Thank you for your feedback!' - }; + const mockBlockSlug = 'test-slug'; + const mockParticipant = { id: 1 }; + const mockFeedbackInfo = { + header: 'Your Feedback', + button: 'Submit', + contact_body: 'Contact us at test@example.com', + thank_you: 'Thank you for your feedback!' + }; - it('renders the feedback form', () => { - const { getByText, getByRole } = render( - - ); + it('renders the feedback form', () => { + const { getByText, getByRole } = render( + + ); - expect(getByText(mockFeedbackInfo.header)).to.exist; - expect(getByRole('textbox')).to.exist; - expect(getByText(mockFeedbackInfo.button)).to.exist; - }); + expect(getByText(mockFeedbackInfo.header)).to.exist; + expect(getByRole('textbox')).to.exist; + expect(getByText(mockFeedbackInfo.button)).to.exist; + }); - it('allows input to be entered', () => { - const { getByRole } = render( - - ); + it('allows input to be entered', () => { + const { getByRole } = render( + + ); - const input = getByRole('textbox'); - fireEvent.change(input, { target: { value: 'Great experience!' } }); + const input = getByRole('textbox'); + fireEvent.change(input, { target: { value: 'Great experience!' } }); - expect(input.value).toBe('Great experience!'); - }); + expect(input.value).toBe('Great experience!'); + }); - it('submits feedback and shows thank you message', async () => { - postFeedback.mockResolvedValueOnce({}); // Mocking resolved promise + it('submits feedback and shows thank you message', async () => { + postFeedback.mockResolvedValueOnce({}); // Mocking resolved promise - const { getByText, getByRole, queryByText } = render( - - ); + const { getByText, getByRole, queryByText } = render( + + ); - fireEvent.change(getByRole('textbox'), { target: { value: 'Great experience!' } }); - fireEvent.click(getByText(mockFeedbackInfo.button)); + fireEvent.change(getByRole('textbox'), { target: { value: 'Great experience!' } }); + fireEvent.click(getByText(mockFeedbackInfo.button)); - await waitFor(() => { - expect(postFeedback).toHaveBeenCalledWith({ - experimentSlug: mockExperimentSlug, - feedback: 'Great experience!', - participant: mockParticipant - }); - expect(queryByText(mockFeedbackInfo.header)).to.not.exist; - expect(getByText(mockFeedbackInfo.thank_you)).to.exist; + await waitFor(() => { + expect(postFeedback).toHaveBeenCalledWith({ + blockSlug: mockBlockSlug, + feedback: 'Great experience!', + participant: mockParticipant + }); + expect(queryByText(mockFeedbackInfo.header)).to.not.exist; + expect(getByText(mockFeedbackInfo.thank_you)).to.exist; + }); }); - }); }); diff --git a/frontend/src/stories/FloatingActionButton.stories.jsx b/frontend/src/stories/FloatingActionButton.stories.jsx index 2ec125ec9..dff8c9dba 100644 --- a/frontend/src/stories/FloatingActionButton.stories.jsx +++ b/frontend/src/stories/FloatingActionButton.stories.jsx @@ -10,7 +10,7 @@ export default { }; const userFeedbackProps = { - experimentSlug: "test", + blockSlug: "test", participant: "test", feedbackInfo: { header: "Feedback", diff --git a/frontend/src/stories/UserFeedback.stories.jsx b/frontend/src/stories/UserFeedback.stories.jsx index 270bbe804..7ec2290e7 100644 --- a/frontend/src/stories/UserFeedback.stories.jsx +++ b/frontend/src/stories/UserFeedback.stories.jsx @@ -10,7 +10,7 @@ export default { export const Default = { args: { - experimentSlug: "test", + blockSlug: "test", participant: "test", feedbackInfo: { header: "Feedback", @@ -34,7 +34,7 @@ export const Default = { export const Vertical = { args: { - experimentSlug: "test", + blockSlug: "test", participant: "test", feedbackInfo: { header: "Feedback",