Skip to content

Commit

Permalink
groups & test
Browse files Browse the repository at this point in the history
  • Loading branch information
tevko committed Dec 13, 2024
1 parent dee5a9d commit 78707a6
Show file tree
Hide file tree
Showing 7 changed files with 205 additions and 122 deletions.
4 changes: 2 additions & 2 deletions client-report/src/components/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,11 @@ import DataUtils from "../util/dataUtils";
import Heading from "./framework/heading.jsx";
import Footer from "./framework/Footer.jsx";
import Overview from "./overview";
import MajorityStrict from "./lists/majorityStrict";
import MajorityStrict from "./lists/majorityStrict.jsx";
import Uncertainty from "./lists/uncertainty";
import UncertaintyNarrative from "./lists/uncertaintyNarrative";
import AllCommentsModeratedIn from "./lists/allCommentsModeratedIn.jsx";
import ParticipantGroups from "./lists/participantGroups";
import ParticipantGroups from "./lists/participantGroups.jsx";
// import CommentsGraph from "./commentsGraph/commentsGraph";
import ParticipantsGraph from "./participantsGraph/participantsGraph";
// import BoxPlot from "./boxPlot/boxPlot";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

import React from "react";
import CommentList from "./commentList.jsx";
import * as globals from "../globals";
import * as globals from "../globals.js";

const Metadata = ({ conversation, comments, ptptCount, formatTid, math, voteColors }) => {
if (!conversation) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
// Copyright (C) 2012-present, The Authors. This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License, version 3, as published by the Free Software Foundation. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see <http://www.gnu.org/licenses/>.

import React from "react";
import * as globals from "../globals";
// import Flex from "../framework/flex"
// import style from "../../util/style";
import * as globals from "../globals.js";
import CommentList from "./commentList.jsx";

const ParticipantGroup = ({
Expand All @@ -12,12 +10,9 @@ const ParticipantGroup = ({
conversation,
comments,
groupVotesForThisGroup,
// groupVotesForOtherGroups,
// demographicsForGroup,
ptptCount,
groupName,
formatTid,
// groupNames,
math,
voteColors,
}) => {
Expand All @@ -27,6 +22,8 @@ const ParticipantGroup = ({
groupLabel = "Group " + globals.groupLabels[gid];
}

console.log(groupComments)

return (
<div
style={{
Expand All @@ -41,13 +38,9 @@ const ParticipantGroup = ({
ptptCount={ptptCount}
math={math}
formatTid={formatTid}
tidsToRender={_.map(groupComments, 'tid') /* uncertainTids would be funnier */}
tidsToRender={groupComments.map(c => c.tid)}
comments={comments}
voteColors={voteColors}/>




</div>
);
};
Expand Down
108 changes: 0 additions & 108 deletions client-report/src/components/lists/participantGroups.js

This file was deleted.

128 changes: 128 additions & 0 deletions client-report/src/components/lists/participantGroups.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
// // Copyright (C) 2012-present, The Authors. This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License, version 3, as published by the Free Software Foundation. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see <http://www.gnu.org/licenses/>.

import React, { useState, useEffect } from "react";
import Group from "./participantGroup.jsx";
import * as globals from "../globals.js";
import Metadata from "./metadata.jsx";

const ParticipantGroups = ({
conversation,
ptptCount,
math,
comments,
style,
voteColors,
formatTid,
demographics,
groupNames,
badTids,
repfulAgreeTidsByGroup,
repfulDisageeTidsByGroup,
report,
}) => {
const [isLoading, setIsLoading] = useState(true);
const [groups, setGroups] = useState([]);

useEffect(() => {
if (!conversation || !math || !comments) return;

const processGroups = () => {
const processedGroups = Object.keys(math["repness"]).map((gid) => { // Use Object.keys and map
gid = Number(gid);

let otherGroupVotes = {
votes: [],
"n-members": 0,
};

const MAX_CLUSTERS = 50;
const temp = math["group-votes"];

for (let ogid = 0; ogid < MAX_CLUSTERS; ogid++) {
if (ogid === gid || !temp[ogid]) {
continue;
}
otherGroupVotes["n-members"] += temp[ogid]["n-members"];
const commentVotes = temp[ogid].votes;

Object.keys(commentVotes || {}).forEach((tid) => { // Use Object.keys and forEach
tid = Number(tid);
const voteObj = commentVotes[tid];
if (voteObj) {
if (!otherGroupVotes.votes[tid]) {
otherGroupVotes.votes[tid] = { A: 0, D: 0, S: 0 };
}
otherGroupVotes.votes[tid].A += voteObj.A;
otherGroupVotes.votes[tid].D += voteObj.D;
otherGroupVotes.votes[tid].S += voteObj.S;
}
});
}

return (
<Group
key={gid}
comments={comments}
gid={gid}
conversation={conversation}
demographicsForGroup={demographics[gid]}
groupComments={math["repness"][gid]} // Access directly
groupName={groupNames[gid]}
groupVotesForThisGroup={math["group-votes"][gid]}
groupVotesForOtherGroups={otherGroupVotes}
formatTid={formatTid}
ptptCount={ptptCount}
groupNames={groupNames}
badTids={badTids}
repfulAgreeTidsByGroup={repfulAgreeTidsByGroup}
repfulDisageeTidsByGroup={repfulDisageeTidsByGroup}
math={math}
report={report}
voteColors={voteColors}
/>
);
});

setGroups(processedGroups);
setIsLoading(false);
};

processGroups();
}, [conversation, math, comments]);

const styles = {
base: {},
...style,
};

return (
<div style={styles}>
<div>
<p style={globals.primaryHeading}> Opinion Groups </p>
<p style={globals.paragraph}>
Across {ptptCount} total participants, {math && Object.keys(math["group-votes"])?.length}{" "}
opinion groups emerged. There are two factors that define an opinion
group. First, each opinion group is made up of a number of participants
who tended to vote similarly on multiple statements. Second, each group
of participants who voted similarly will have also voted distinctly
differently from other groups.
</p>
<Metadata
math={math}
comments={comments}
conversation={conversation}
ptptCount={ptptCount}
voteColors={voteColors}
formatTid={formatTid}
/>
{isLoading ? (
<div>Loading Groups</div>
) : (
groups
)}
</div>
</div>
);
};

export default ParticipantGroups;
70 changes: 70 additions & 0 deletions client-report/src/components/lists/participantGroups.test.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
import React from 'react';
import { render, screen } from '@testing-library/react';
import ParticipantGroups from './ParticipantGroups';
import * as globals from '../globals'; // Mock globals if necessary
import Metadata from './metadata.jsx'; // Mock Metadata
import Group from './participantGroup.jsx'; // Mock Group
import '@testing-library/jest-dom';

jest.mock('../globals', () => ({
primaryHeading: { fontSize: '20px' },
paragraph: { fontSize: '16px' },
}));

jest.mock('./metadata.jsx', () => () => <div data-testid="mock-metadata" />);
jest.mock('./participantGroup.jsx', () => ({ groupName }) => (
<div data-testid={`mock-group-${groupName}`}>{groupName}</div>
));

describe('ParticipantGroups Component', () => {
const mockProps = {
conversation: {},
ptptCount: 100,
math: {
"group-votes": {
0: { "n-members": 20, votes: { 1: { A: 10, D: 5, S: 5 }, 2: { A: 15, D: 0, S: 5 } } },
1: { "n-members": 30, votes: { 1: { A: 5, D: 15, S: 10 }, 3: { A: 20, D: 5, S: 5 } } },
},
repness: {
0: { someData: 'group0data' },
1: { someData: 'group1data' },
},
},
comments: {},
voteColors: {},
formatTid: jest.fn((tid) => `TID${tid}`),
demographics: {
0: {someDemo: "demo0"},
1: {someDemo: "demo1"}
},
groupNames: {
0: "Group A",
1: "Group B"
},
badTids: [],
repfulAgreeTidsByGroup: {},
repfulDisageeTidsByGroup: {},
report: {},
style: { backgroundColor: 'lightgray' }
};

it('renders loading message when data is missing', () => {
render(<ParticipantGroups />);
expect(screen.getByText('Loading Groups')).toBeInTheDocument();
});

it('renders component with groups when data is present', () => {
render(<ParticipantGroups {...mockProps} />);

expect(screen.getByText('Opinion Groups')).toBeInTheDocument();
expect(screen.getByText(/Across 100 total participants, 2 opinion groups emerged/)).toBeInTheDocument();
expect(screen.getByTestId('mock-metadata')).toBeInTheDocument();
expect(screen.getByTestId('mock-group-Group A')).toBeInTheDocument();
expect(screen.getByTestId('mock-group-Group B')).toBeInTheDocument();
});

it("renders correct number of groups", () => {
render(<ParticipantGroups {...mockProps} />);
expect(screen.getAllByTestId(/mock-group-/).length).toBe(2);
})
});

0 comments on commit 78707a6

Please sign in to comment.