Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
<template>

<span
class="studio-chip"
:class="{ notranslate }"
:style="chipStyle"
>
<slot></slot>
</span>

</template>


<script>

export default {
name: 'StudioChip',
props: {
notranslate: {
type: Boolean,
default: false,
},
},
computed: {
chipStyle() {
return {
color: this.$themeTokens.text,
backgroundColor: this.$themePalette.grey.v_200,
};
},
},
};

</script>


<style lang="scss" scoped>

.studio-chip {
display: inline-block;
padding: 4px 8px;
margin: 2px 4px 2px 0;
font-size: 12px;
font-weight: bold;
line-height: 16px;
border-radius: 10px;
}

</style>
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
import { render, screen } from '@testing-library/vue';
import VueRouter from 'vue-router';
import StudioChip from '../StudioChip.vue';

const router = new VueRouter({
routes: [],
});

describe('StudioChip', () => {
it('renders chip with text content', () => {
render(StudioChip, {
router,
slots: {
default: 'Test Tag',
},
});

expect(screen.getByText('Test Tag')).toBeInTheDocument();
});

it('applies notranslate class when prop is true', () => {
const { container } = render(StudioChip, {
router,
props: {
notranslate: true,
},
slots: {
default: 'User Content',
},
});

const chip = container.querySelector('.studio-chip');
expect(chip).toHaveClass('notranslate');
});

it('does not apply notranslate class when prop is false', () => {
const { container } = render(StudioChip, {
router,
props: {
notranslate: false,
},
slots: {
default: 'Regular Content',
},
});

const chip = container.querySelector('.studio-chip');
expect(chip).not.toHaveClass('notranslate');
});

it('renders multiple chips independently', () => {
const { container: container1 } = render(StudioChip, {
router,
slots: {
default: 'Chip 1',
},
});

const { container: container2 } = render(StudioChip, {
router,
slots: {
default: 'Chip 2',
},
});

expect(container1.querySelector('.studio-chip')).toHaveTextContent('Chip 1');
expect(container2.querySelector('.studio-chip')).toHaveTextContent('Chip 2');
});

it('has correct styling classes', () => {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can be removed.

We typically don't test styling or classes in unit tests - it doesn't say that much about resulting experience. And is extra maintenance - when class or style is removed or renamed, we'd need to update test.

Generally in all our tests you can focus on testing (1) rendered content, (2) business logic. Please revisit other tests too.

const { container } = render(StudioChip, {
router,
slots: {
default: 'Styled Chip',
},
});

const chip = container.querySelector('.studio-chip');
expect(chip).toBeTruthy();
expect(chip.tagName).toBe('SPAN');
});
});
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This test suite needs to test things like

  • If a channel has levels, a corresponding text is rendered
  • If a channel has no levels, --- is rendered

This is just one of many examples. Same applies for all other information on the page - preview it as a user for channel with/without data, and then make unit tests to document the behavior.

Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
import { render } from '@testing-library/vue';
import VueRouter from 'vue-router';
import StudioDetailsPanel from '../details/StudioDetailsPanel.vue';

const router = new VueRouter({
routes: [],
});

const mockChannelDetails = {
name: 'Test Channel',
description: 'Test channel description',
thumbnail_url: null,
published: true,
version: 1,
primary_token: 'test-token',
language: 'en',
resource_count: 10,
kind_count: [],
};

describe('StudioDetailsPanel', () => {
it('renders without crashing with minimal props', () => {
const { container } = render(StudioDetailsPanel, {
router,
props: {
details: {},
isChannel: false,
loading: false,
},
mocks: {
$formatNumber: jest.fn(n => String(n)),
$formatDate: jest.fn(() => 'Test Date'),
$tr: jest.fn(key => key),
},
});

expect(container).toBeInTheDocument();
});

it('displays loader when loading is true', () => {
const { container } = render(StudioDetailsPanel, {
router,
props: {
details: {},
isChannel: true,
loading: true,
},
mocks: {
$formatNumber: jest.fn(n => String(n)),
$formatDate: jest.fn(() => 'Test Date'),
$tr: jest.fn(key => key),
},
});

expect(container).toBeInTheDocument();
});

it('renders channel information', () => {
const { container } = render(StudioDetailsPanel, {
router,
props: {
details: mockChannelDetails,
isChannel: true,
loading: false,
},
mocks: {
$formatNumber: jest.fn(n => String(n)),
$formatDate: jest.fn(() => 'Test Date'),
$tr: jest.fn(key => key),
},
});

expect(container).toHaveTextContent('Test Channel');
});

it('does not use VDataTable', () => {
const { container } = render(StudioDetailsPanel, {
router,
props: {
details: mockChannelDetails,
isChannel: true,
loading: false,
},
mocks: {
$formatNumber: jest.fn(n => String(n)),
$formatDate: jest.fn(() => 'Test Date'),
$tr: jest.fn(key => key),
},
});

expect(container.querySelector('.v-datatable')).not.toBeInTheDocument();
});

it('does not use VChip', () => {
const { container } = render(StudioDetailsPanel, {
router,
props: {
details: mockChannelDetails,
isChannel: true,
loading: false,
},
mocks: {
$formatNumber: jest.fn(n => String(n)),
$formatDate: jest.fn(() => 'Test Date'),
$tr: jest.fn(key => key),
},
});

expect(container.querySelector('.v-chip')).not.toBeInTheDocument();
});

it('does not use VLayout or VFlex', () => {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Users are not interested in our Vuetify refactor - for them it doesn't matter if we use VFlex or flex style. And after Vuetify is removed from Studio, what would be value of testing this?

Would you find some articles around good unit testing practices, and also have a look at VTL guiding principles? For each test scenario you write, reflect critically on why is the scenario useful or not, and what it tests from the user point of view.

const { container } = render(StudioDetailsPanel, {
router,
props: {
details: mockChannelDetails,
isChannel: true,
loading: false,
},
mocks: {
$formatNumber: jest.fn(n => String(n)),
$formatDate: jest.fn(() => 'Test Date'),
$tr: jest.fn(key => key),
},
});

expect(container.querySelector('.v-layout')).not.toBeInTheDocument();
expect(container.querySelector('.v-flex')).not.toBeInTheDocument();
});
});
Loading