Skip to content
This repository has been archived by the owner on Nov 27, 2022. It is now read-only.

Commit

Permalink
Add DislikeButton.
Browse files Browse the repository at this point in the history
  • Loading branch information
RubenVerborgh committed Mar 20, 2019
1 parent 70db965 commit 2d896aa
Show file tree
Hide file tree
Showing 5 changed files with 277 additions and 1 deletion.
7 changes: 6 additions & 1 deletion demo/index.css
Expand Up @@ -29,9 +29,14 @@ body {
.solid.activity:hover {
text-decoration: underline;
}
.solid.activity::before {
display: inline-block;
}
.solid.like::before {
content: '👍 ';
display: inline-block;
}
.solid.dislike::before {
content: '👎 ';
}

img.profile {
Expand Down
19 changes: 19 additions & 0 deletions src/components/DislikeButton.jsx
@@ -0,0 +1,19 @@
import React from 'react';
import data from '@solid/query-ldflex';
import ActivityButton from './ActivityButton';

const { as } = data.context;

/** Button to view and perform a "Dislike" action on an item. */
export default function DislikeButton({
object,
children = object ? null : 'this page',
likeText = 'Dislike',
likedText = children ? 'You disliked' : 'Disliked',
likeLabel = children ? [likeText, ' ', children] : likeText,
likedLabel = children ? [likedText, ' ', children] : likedText,
...props
}) {
return <ActivityButton activityType={`${as}Dislike`} object={object}
suggestActivity={likeLabel} displayActivity={likedLabel} {...props} />;
}
3 changes: 3 additions & 0 deletions src/index.js
Expand Up @@ -24,6 +24,7 @@ import List from './components/List';
import LiveUpdate from './components/LiveUpdate';
import ActivityButton from './components/ActivityButton';
import LikeButton from './components/LikeButton';
import DislikeButton from './components/DislikeButton';

import UpdateContext from './UpdateContext';

Expand Down Expand Up @@ -57,6 +58,8 @@ export {
ActivityButton,
LikeButton,
LikeButton as Like,
DislikeButton,
DislikeButton as Dislike,

UpdateContext,
};
247 changes: 247 additions & 0 deletions test/components/DislikeButton-test.jsx
@@ -0,0 +1,247 @@
import React from 'react';
import { DislikeButton } from '../../src/';
import { render, fireEvent, cleanup } from 'react-testing-library';
import MockPromise from 'jest-mock-promise';
import data from '@solid/query-ldflex';
import useLDflex from '../../src/hooks/useLDflex';

jest.mock('../../src/hooks/useLDflex', () => require('../__mocks__/useLDflex'));

const currentUrl = 'https://example.org/page/#fragment';
const dislike = 'https://www.w3.org/ns/activitystreams#Dislike';

describe('A DislikeButton', () => {
let button;
beforeAll(() => {
window.location.href = currentUrl;
});
afterEach(cleanup);

describe('without attributes', () => {
const findExpression = `[${currentUrl}].findActivity("${dislike}")`;
const createExpression = `[${currentUrl}].createActivity("${dislike}")`;
const deleteExpression = `[${currentUrl}].deleteActivity("${dislike}")`;

beforeEach(() => {
data.resolve.mockClear();
const { container } = render(<DislikeButton/>);
button = container.firstChild;
});

it('has the "solid" class', () => {
expect(button).toHaveClass('solid');
});

it('has the "activity" class', () => {
expect(button).toHaveClass('solid');
});

it('has the "dislike" class', () => {
expect(button).toHaveClass('dislike');
});

it('does not have the "performed" class', () => {
expect(button).not.toHaveClass('performed');
});

it('has "Dislike this page" as a label', () => {
expect(button).toHaveProperty('innerHTML', 'Dislike this page');
});

describe('when no activity exists', () => {
beforeEach(() => {
useLDflex.resolve(findExpression, undefined);
});

it('has "Dislike this page" as a label', () => {
expect(button).toHaveProperty('innerHTML', 'Dislike this page');
});

it('does not have the "performed" class', () => {
expect(button).not.toHaveClass('performed');
});

describe('when clicked', () => {
let activity;
beforeEach(() => {
activity = new MockPromise();
data.resolve.mockReturnValue(activity);
fireEvent.click(button);
});

it('has "You disliked this page" as a label', () => {
expect(button).toHaveProperty('innerHTML', 'You disliked this page');
});

it('has the "performed" class', () => {
expect(button).toHaveClass('performed');
});

it('creates an activity', () => {
expect(data.resolve).toHaveBeenCalledWith(createExpression);
});

describe('when activity creation succeeds', () => {
beforeEach(() => {
// mute `act` warning caused by asynchronous `reject`,
// since no workaround currently exists
// https://github.com/facebook/jest/issues/7151
console.mute();
activity.resolve({});
});
afterEach(() => {
console.unmute();
});

it('has "You disliked this page" as a label', () => {
expect(button).toHaveProperty('innerHTML', 'You disliked this page');
});

it('has the "performed" class', () => {
expect(button).toHaveClass('performed');
});
});

describe('when activity creation fails', () => {
beforeEach(() => {
console.mute();
activity.reject(new Error());
});
afterEach(() => {
console.unmute();
});

it('has "Dislike this page" as a label', () => {
expect(button).toHaveProperty('innerHTML', 'Dislike this page');
});

it('does not have the "performed" class', () => {
expect(button).not.toHaveClass('performed');
});
});
});
});

describe('when an activity exists', () => {
beforeEach(() => {
useLDflex.resolve(findExpression, {});
});

it('has "You disliked this page" as a label', () => {
expect(button).toHaveProperty('innerHTML', 'You disliked this page');
});

it('has the "performed" class', () => {
expect(button).toHaveClass('performed');
});

describe('when clicked', () => {
let activity;
beforeEach(() => {
activity = new MockPromise();
data.resolve.mockReturnValue(activity);
fireEvent.click(button);
});

it('has "Dislike this page" as a label', () => {
expect(button).toHaveProperty('innerHTML', 'Dislike this page');
});

it('does not have the "performed" class', () => {
expect(button).not.toHaveClass('performed');
});

it('creates an activity', () => {
expect(data.resolve).toHaveBeenCalledWith(deleteExpression);
});

describe('when activity creation succeeds', () => {
beforeEach(() => {
console.mute();
activity.resolve({});
});
afterEach(() => {
console.unmute();
});

it('has "Dislike this page" as a label', () => {
expect(button).toHaveProperty('innerHTML', 'Dislike this page');
});

it('does not have the "performed" class', () => {
expect(button).not.toHaveClass('performed');
});
});

describe('when activity creation fails', () => {
beforeEach(() => {
console.mute();
activity.reject(new Error());
});
afterEach(() => {
console.unmute();
});

it('has "You disliked this page" as a label', () => {
expect(button).toHaveProperty('innerHTML', 'You disliked this page');
});

it('has the "performed" class', () => {
expect(button).toHaveClass('performed');
});
});
});
});
});

describe('with an object', () => {
const object = 'https://example.org/#thing';
const findExpression = `["${object}"].findActivity("${dislike}")`;
const createExpression = `["${object}"].createActivity("${dislike}")`;

beforeEach(() => {
data.resolve.mockClear();
const { container } = render(<DislikeButton object={object}/>);
button = container.firstChild;
});

describe('when no activity exists', () => {
beforeEach(() => {
useLDflex.resolve(findExpression, undefined);
});

it('has "Dislike" as a label', () => {
expect(button).toHaveProperty('innerHTML', 'Dislike');
});

describe('when clicked', () => {
let activity;
beforeEach(() => {
activity = new MockPromise();
data.resolve.mockReturnValue(activity);
fireEvent.click(button);
});

it('has "Disliked" as a label', () => {
expect(button).toHaveProperty('innerHTML', 'Disliked');
});

it('creates an activity', () => {
expect(data.resolve).toHaveBeenCalledWith(createExpression);
});
});
});
});

describe('with children', () => {
beforeEach(() => {
data.resolve.mockClear();
const { container } = render(<DislikeButton>this thing</DislikeButton>);
button = container.firstChild;
});

it('has "Dislike this thing" as a label', () => {
expect(button).toHaveProperty('innerHTML', 'Dislike this thing');
});
});
});
2 changes: 2 additions & 0 deletions test/index-test.js
Expand Up @@ -28,6 +28,8 @@ describe('The SolidReactComponents module', () => {
'ActivityButton',
'LikeButton',
'Like',
'DislikeButton',
'Dislike',

'UpdateContext',
];
Expand Down

0 comments on commit 2d896aa

Please sign in to comment.