Skip to content

Commit

Permalink
Add popularity statistics
Browse files Browse the repository at this point in the history
  • Loading branch information
ajuvonen committed Nov 7, 2024
1 parent 990bfd2 commit 9f5499b
Show file tree
Hide file tree
Showing 9 changed files with 414 additions and 18 deletions.
56 changes: 56 additions & 0 deletions src/components/PopularityStatistics.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
<script lang="ts" setup>
import {storeToRefs} from 'pinia';
import {useActivityStore} from '@/stores/activityStore';
import ContentElement from '@/components/ContentElement.vue';
const {categoryFavorites} = storeToRefs(useActivityStore());
</script>
<template>
<div class="popularity__container">
<ContentElement
v-for="[category, favorites] in categoryFavorites"
:key="category"
:title="$t(`popularity.${category}`)"
>
<ul class="flex-container flex-col align-start">
<li
v-for="(emoji, index) in ['πŸ₯‡', 'πŸ₯ˆ', 'πŸ₯‰']"
:key="emoji"
class="popularity__entry"
:data-test-id="`popularity-${category}-${index + 1}`"
>
<div class="popularity__entry-emoji" aria-hidden="true">{{ emoji }}</div>
<div v-if="favorites[index]" class="popularity__entry-text">
{{
$t('popularity.entry', [$t(`veggies.${favorites[index][0]}`), favorites[index][1]])
}}
</div>
<div v-else class="popularity__entry-text">{{ $t('popularity.noEntry') }}</div>
</li>
</ul>
</ContentElement>
</div>
</template>
<style lang="scss" scoped>
.popularity__container {
@apply flex-container flex-col gap-4;
@apply has-scroll;
}
.popularity__entry {
@apply flex items-center;
}
.popularity__entry-emoji {
@apply text-4xl;
filter: drop-shadow(0 0 2px #fff);
}
.popularity__entry-text {
@apply capitalize;
}
.popularity__honorable-mentions {
@apply capitalize list-decimal list-inside;
}
</style>
88 changes: 88 additions & 0 deletions src/components/__tests__/PopularityStatistics.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
import {describe, it, expect, beforeEach} from 'vitest';
import {mount} from '@vue/test-utils';
import {DateTime} from 'luxon';
import {useActivityStore} from '@/stores/activityStore';
import PopularityStatistics from '@/components/PopularityStatistics.vue';
import {Category} from '@/utils/types';

const thisWeek = DateTime.now().startOf('week');
const lastWeek = DateTime.now().startOf('week').minus({weeks: 1});
const twoWeeksAgo = DateTime.now().startOf('week').minus({weeks: 2});

describe('PopularityStatistics', () => {
let activityStore: ReturnType<typeof useActivityStore>;
beforeEach(() => {
activityStore = useActivityStore();
});

it('renders empty', () => {
const wrapper = mount(PopularityStatistics);
expect(wrapper.html()).toMatchSnapshot();
});

it('renders with data', () => {
activityStore.startDate = thisWeek;
activityStore.weeks.push({
startDate: thisWeek,
veggies: ['apple', 'cucumber', 'romaine', 'potato', 'red bean', 'teff'],
});

const wrapper = mount(PopularityStatistics);
expect(wrapper.findByTestId('popularity-Fruit-1').find('.popularity__entry-text').text()).toBe(
'apple (1)',
);
expect(
wrapper.findByTestId('popularity-Vegetable-1').find('.popularity__entry-text').text(),
).toBe('cucumber (1)');
expect(wrapper.findByTestId('popularity-Leafy-1').find('.popularity__entry-text').text()).toBe(
'romaine (1)',
);
expect(wrapper.findByTestId('popularity-Root-1').find('.popularity__entry-text').text()).toBe(
'potato (1)',
);
expect(wrapper.findByTestId('popularity-Bean-1').find('.popularity__entry-text').text()).toBe(
'red bean (1)',
);
expect(wrapper.findByTestId('popularity-Grain-1').find('.popularity__entry-text').text()).toBe(
'teff (1)',
);

Object.values(Category).forEach((category) => {
expect(
wrapper.findByTestId(`popularity-${category}-2`).find('.popularity__entry-text').text(),
).toBe('No Entry');
expect(
wrapper.findByTestId(`popularity-${category}-3`).find('.popularity__entry-text').text(),
).toBe('No Entry');
});
});

it('renders entries in correct order', () => {
activityStore.startDate = twoWeeksAgo;
activityStore.weeks.push(
{
startDate: twoWeeksAgo,
veggies: ['apple', 'lychee', 'pineapple'],
},
{
startDate: lastWeek,
veggies: ['apple', 'lychee', 'longan'],
},
{
startDate: thisWeek,
veggies: ['apple', 'blueberry', 'cloudberry'],
},
);

const wrapper = mount(PopularityStatistics);
expect(wrapper.findByTestId('popularity-Fruit-1').find('.popularity__entry-text').text()).toBe(
'apple (3)',
);
expect(wrapper.findByTestId('popularity-Fruit-2').find('.popularity__entry-text').text()).toBe(
'lychee (2)',
);
expect(wrapper.findByTestId('popularity-Fruit-3').find('.popularity__entry-text').text()).toBe(
'pineapple (1)',
);
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html

exports[`PopularityStatistics > renders empty 1`] = `
"<div data-v-4cf0b303="" class="popularity__container">
<div data-v-4cf0b303="" class="flex-container flex-col">
<h2 class="label-like" aria-hidden="false">Top-3 Fruits And Berries</h2>
<ul data-v-4cf0b303="" class="flex-container flex-col align-start">
<li data-v-4cf0b303="" class="popularity__entry" data-test-id="popularity-Fruit-1">
<div data-v-4cf0b303="" class="popularity__entry-emoji" aria-hidden="true">πŸ₯‡</div>
<div data-v-4cf0b303="" class="popularity__entry-text">No Entry</div>
</li>
<li data-v-4cf0b303="" class="popularity__entry" data-test-id="popularity-Fruit-2">
<div data-v-4cf0b303="" class="popularity__entry-emoji" aria-hidden="true">πŸ₯ˆ</div>
<div data-v-4cf0b303="" class="popularity__entry-text">No Entry</div>
</li>
<li data-v-4cf0b303="" class="popularity__entry" data-test-id="popularity-Fruit-3">
<div data-v-4cf0b303="" class="popularity__entry-emoji" aria-hidden="true">πŸ₯‰</div>
<div data-v-4cf0b303="" class="popularity__entry-text">No Entry</div>
</li>
</ul>
</div>
<div data-v-4cf0b303="" class="flex-container flex-col">
<h2 class="label-like" aria-hidden="false">Top-3 Vegetables</h2>
<ul data-v-4cf0b303="" class="flex-container flex-col align-start">
<li data-v-4cf0b303="" class="popularity__entry" data-test-id="popularity-Vegetable-1">
<div data-v-4cf0b303="" class="popularity__entry-emoji" aria-hidden="true">πŸ₯‡</div>
<div data-v-4cf0b303="" class="popularity__entry-text">No Entry</div>
</li>
<li data-v-4cf0b303="" class="popularity__entry" data-test-id="popularity-Vegetable-2">
<div data-v-4cf0b303="" class="popularity__entry-emoji" aria-hidden="true">πŸ₯ˆ</div>
<div data-v-4cf0b303="" class="popularity__entry-text">No Entry</div>
</li>
<li data-v-4cf0b303="" class="popularity__entry" data-test-id="popularity-Vegetable-3">
<div data-v-4cf0b303="" class="popularity__entry-emoji" aria-hidden="true">πŸ₯‰</div>
<div data-v-4cf0b303="" class="popularity__entry-text">No Entry</div>
</li>
</ul>
</div>
<div data-v-4cf0b303="" class="flex-container flex-col">
<h2 class="label-like" aria-hidden="false">Top-3 Leafy Greens And Herbs</h2>
<ul data-v-4cf0b303="" class="flex-container flex-col align-start">
<li data-v-4cf0b303="" class="popularity__entry" data-test-id="popularity-Leafy-1">
<div data-v-4cf0b303="" class="popularity__entry-emoji" aria-hidden="true">πŸ₯‡</div>
<div data-v-4cf0b303="" class="popularity__entry-text">No Entry</div>
</li>
<li data-v-4cf0b303="" class="popularity__entry" data-test-id="popularity-Leafy-2">
<div data-v-4cf0b303="" class="popularity__entry-emoji" aria-hidden="true">πŸ₯ˆ</div>
<div data-v-4cf0b303="" class="popularity__entry-text">No Entry</div>
</li>
<li data-v-4cf0b303="" class="popularity__entry" data-test-id="popularity-Leafy-3">
<div data-v-4cf0b303="" class="popularity__entry-emoji" aria-hidden="true">πŸ₯‰</div>
<div data-v-4cf0b303="" class="popularity__entry-text">No Entry</div>
</li>
</ul>
</div>
<div data-v-4cf0b303="" class="flex-container flex-col">
<h2 class="label-like" aria-hidden="false">Top-3 Roots And Bulbs</h2>
<ul data-v-4cf0b303="" class="flex-container flex-col align-start">
<li data-v-4cf0b303="" class="popularity__entry" data-test-id="popularity-Root-1">
<div data-v-4cf0b303="" class="popularity__entry-emoji" aria-hidden="true">πŸ₯‡</div>
<div data-v-4cf0b303="" class="popularity__entry-text">No Entry</div>
</li>
<li data-v-4cf0b303="" class="popularity__entry" data-test-id="popularity-Root-2">
<div data-v-4cf0b303="" class="popularity__entry-emoji" aria-hidden="true">πŸ₯ˆ</div>
<div data-v-4cf0b303="" class="popularity__entry-text">No Entry</div>
</li>
<li data-v-4cf0b303="" class="popularity__entry" data-test-id="popularity-Root-3">
<div data-v-4cf0b303="" class="popularity__entry-emoji" aria-hidden="true">πŸ₯‰</div>
<div data-v-4cf0b303="" class="popularity__entry-text">No Entry</div>
</li>
</ul>
</div>
<div data-v-4cf0b303="" class="flex-container flex-col">
<h2 class="label-like" aria-hidden="false">Top-3 Beans And Legumes</h2>
<ul data-v-4cf0b303="" class="flex-container flex-col align-start">
<li data-v-4cf0b303="" class="popularity__entry" data-test-id="popularity-Bean-1">
<div data-v-4cf0b303="" class="popularity__entry-emoji" aria-hidden="true">πŸ₯‡</div>
<div data-v-4cf0b303="" class="popularity__entry-text">No Entry</div>
</li>
<li data-v-4cf0b303="" class="popularity__entry" data-test-id="popularity-Bean-2">
<div data-v-4cf0b303="" class="popularity__entry-emoji" aria-hidden="true">πŸ₯ˆ</div>
<div data-v-4cf0b303="" class="popularity__entry-text">No Entry</div>
</li>
<li data-v-4cf0b303="" class="popularity__entry" data-test-id="popularity-Bean-3">
<div data-v-4cf0b303="" class="popularity__entry-emoji" aria-hidden="true">πŸ₯‰</div>
<div data-v-4cf0b303="" class="popularity__entry-text">No Entry</div>
</li>
</ul>
</div>
<div data-v-4cf0b303="" class="flex-container flex-col">
<h2 class="label-like" aria-hidden="false">Top-3 Grains, Nuts, And Seeds</h2>
<ul data-v-4cf0b303="" class="flex-container flex-col align-start">
<li data-v-4cf0b303="" class="popularity__entry" data-test-id="popularity-Grain-1">
<div data-v-4cf0b303="" class="popularity__entry-emoji" aria-hidden="true">πŸ₯‡</div>
<div data-v-4cf0b303="" class="popularity__entry-text">No Entry</div>
</li>
<li data-v-4cf0b303="" class="popularity__entry" data-test-id="popularity-Grain-2">
<div data-v-4cf0b303="" class="popularity__entry-emoji" aria-hidden="true">πŸ₯ˆ</div>
<div data-v-4cf0b303="" class="popularity__entry-text">No Entry</div>
</li>
<li data-v-4cf0b303="" class="popularity__entry" data-test-id="popularity-Grain-3">
<div data-v-4cf0b303="" class="popularity__entry-emoji" aria-hidden="true">πŸ₯‰</div>
<div data-v-4cf0b303="" class="popularity__entry-text">No Entry</div>
</li>
</ul>
</div>
</div>"
`;
Loading

0 comments on commit 9f5499b

Please sign in to comment.