Skip to content

Commit

Permalink
update comment actions block
Browse files Browse the repository at this point in the history
  • Loading branch information
akellbl4 authored and umputun committed Apr 15, 2022
1 parent cd7a2a3 commit 58b0841
Show file tree
Hide file tree
Showing 46 changed files with 595 additions and 493 deletions.
7 changes: 0 additions & 7 deletions frontend/app/common/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -129,14 +129,7 @@ export interface Config {
}

export type Sorting = '-time' | '+time' | '-active' | '+active' | '-score' | '+score' | '-controversy' | '+controversy';

export type BlockTTL = 'permanently' | '43200m' | '10080m' | '1440m';

export interface BlockingDuration {
label: string;
value: BlockTTL;
}

export type Theme = 'light' | 'dark';

/**
Expand Down
19 changes: 18 additions & 1 deletion frontend/app/components/auth/components/button.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@
}
}

.link {
.hollow {
color: rgb(var(--primary-color));
background-color: unset;
text-transform: initial;
Expand All @@ -87,6 +87,23 @@
}
}

.link {
composes: hollow;
border: 0;
padding: 2px;
font-weight: 600;

&:hover {
background-color: unset;
color: rgb(var(--primary-brighter-color));
}
}

.link[disabled] {
background-color: unset;
color: rgba(var(--primary-color), 0.9);
}

:global(.dark) {
& .button {
border-color: rgba(var(--white-color), 0.1);
Expand Down
2 changes: 1 addition & 1 deletion frontend/app/components/auth/components/button.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import styles from './button.module.css';

type Props = Omit<JSX.HTMLAttributes<HTMLButtonElement>, 'size'> & {
size?: 'xs' | 'sm';
kind?: 'transparent' | 'link';
kind?: 'transparent' | 'link' | 'hollow';
suffix?: VNode;
loading?: boolean;
selected?: boolean;
Expand Down

This file was deleted.

16 changes: 0 additions & 16 deletions frontend/app/components/comment/__action/comment__action.css

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

16 changes: 0 additions & 16 deletions frontend/app/components/comment/__controls/comment__controls.css

This file was deleted.

This file was deleted.

32 changes: 32 additions & 0 deletions frontend/app/components/comment/comment-actions.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
.root {
display: flex;
align-items: center;
font-size: 14px;
color: rgb(var(--primary-color));
}

.root > * + *,
.additionalActions > * + * {
margin-left: 0.5em;
}

.countdown {
color: rgb(var(--secondary-darker-text-color));
}

@media (hover: hover) {
.additionalActions {
opacity: 0;
transition: opacity 0.15s;
}

.root:hover .additionalActions {
opacity: 1;
}
}

.additionalActions::before {
content: '•';
color: rgb(var(--secondary-text-color));
margin-right: 0.5em;
}
143 changes: 143 additions & 0 deletions frontend/app/components/comment/comment-actions.spec.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
import { h } from 'preact';
import '@testing-library/jest-dom';
import { CommentActions, Props } from './comment-actions';
import { render } from 'tests/utils';
import { screen, waitFor } from '@testing-library/preact';

function getProps(): Props {
return {
pinned: false,
admin: false,
currentUser: false,
copied: false,
bannedUser: false,
readOnly: false,
editing: false,
replying: false,
onCopy() {},
onDelete() {},
onTogglePin() {},
onToggleReplying() {},
onHideUser() {},
onBlockUser() {},
onUnblockUser() {},
onDisableEditing() {},
editable: false,
editDeadline: undefined,
};
}
describe('<CommentActions/>', () => {
let props: Props;

beforeEach(() => {
props = getProps();
});

it('should render "Reply"', () => {
render(<CommentActions {...props} />);
expect(screen.getByText('Reply')).toBeVisible();
});

it('should not render "Reply" in read only mode', () => {
props.readOnly = true;
render(<CommentActions {...props} />);
expect(screen.queryByText('Reply')).not.toBeInTheDocument();
});

it('should not render "Cancel" instead "Reply" in replying mode', () => {
props.replying = true;
render(<CommentActions {...props} />);
expect(screen.queryByText('Reply')).not.toBeInTheDocument();
expect(screen.getByText('Cancel')).toBeInTheDocument();
});

it('should render "Hide" on comments not from currentUser', () => {
props.currentUser = false;
render(<CommentActions {...props} />);
expect(screen.getByText('Hide')).toBeVisible();
});

it('should not render "Hide" on comments not from currentUser', () => {
props.currentUser = true;
render(<CommentActions {...props} />);
expect(screen.queryByText('Hide')).not.toBeInTheDocument();
});

it('should render "Edit" and timer when editing is available', async () => {
Object.assign(props, { editable: true, editDeadline: Date.now() + 300 * 1000 });
render(<CommentActions {...props} />);
expect(screen.getByText('Edit')).toBeInTheDocument();
await waitFor(() => expect(['300s', '299s']).toContain(screen.getByRole('timer').textContent));
});

it('should render "Cancel" instead "Edit" in editing mode', async () => {
Object.assign(props, { editable: true, editing: true, editDeadline: Date.now() + 300 * 1000 });
render(<CommentActions {...props} />);
expect(screen.getByText('Cancel')).toBeInTheDocument();
});

it.each([
[{ editable: false, editDeadline: Date.now() + 300 * 1000 }],
[{ editable: true, editDeadline: undefined }],
] as Partial<Props>[][])('should not render "Edit" when editing is not available', (override) => {
Object.assign(props, override);
render(<CommentActions {...props} />);
expect(screen.getByText('Hide')).toBeInTheDocument();
});

it('should render "Delete" for current user comments', () => {
props.currentUser = true;
render(<CommentActions {...props} />);
expect(screen.getByText('Delete')).toBeInTheDocument();
});

it('should not render "Delete" for other users comments', () => {
render(<CommentActions {...props} />);
expect(screen.queryByText('Delete')).not.toBeInTheDocument();
});

describe('admin actions', () => {
it('should render "Copy"', () => {
props.admin = true;
render(<CommentActions {...props} />);
expect(screen.getByText('Copy')).toBeInTheDocument();
});

it('should render "Copied" when comment copied', () => {
Object.assign(props, { admin: true, copied: true });
render(<CommentActions {...props} />);
expect(screen.getByText('Copied!')).toBeInTheDocument();
});

it('should render "Pin"', () => {
props.admin = true;
render(<CommentActions {...props} />);
expect(screen.getByText('Pin')).toBeInTheDocument();
});

it('should render "Unpin" when comment is pinned', () => {
Object.assign(props, { admin: true, pinned: true });
render(<CommentActions {...props} />);
expect(screen.getByText('Unpin')).toBeInTheDocument();
});

it.each([[{ currentUser: false, admin: true }], [{ currentUser: true, admin: true }]] as Partial<Props>[][])(
'should render "Delete" on all comments for admin',
(override) => {
Object.assign(props, override);
render(<CommentActions {...props} />);
expect(screen.getByText('Delete')).toBeInTheDocument();
}
);

it('should render admin actions in right order', () => {
props.admin = true;
render(<CommentActions {...props} />);
expect(screen.getByTestId('comment-actions-additional').children[0]).toHaveTextContent('Hide');
expect(screen.getByTestId('comment-actions-additional').children[1]).toHaveTextContent('Copy');
expect(screen.getByTestId('comment-actions-additional').children[2]).toHaveTextContent('Pin');
expect(screen.getByTestId('comment-actions-additional').children[3]).toHaveTextContent('Block');
expect(screen.getByTestId('comment-actions-additional').children[4]).toHaveTextContent('Delete');
});
});
});
Loading

0 comments on commit 58b0841

Please sign in to comment.