Skip to content

Commit

Permalink
Merge pull request #207 from JHWelch/cleanup
Browse files Browse the repository at this point in the history
Cleanup
  • Loading branch information
JHWelch authored Oct 31, 2024
2 parents b1e545e + a12ab55 commit 5db5b2a
Show file tree
Hide file tree
Showing 4 changed files with 205 additions and 44 deletions.
26 changes: 26 additions & 0 deletions client/src/components/admin/Info.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<script setup lang="ts">
withDefaults(defineProps<{
title: string
value: string
style?: 'small' | 'large'
}>(), {
style: 'small',
})
</script>

<template>
<div
:class="{
'flex flex-col items-center w-full p-3 rounded-md bg-brat-300': true,
'col-span-2': style === 'large',
}"
>
<div class="font-semibold">
{{ title }}
</div>

<div :class="{ 'text-6xl': style === 'small' }">
{{ value }}
</div>
</div>
</template>
55 changes: 55 additions & 0 deletions client/src/components/admin/__tests__/Info.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
/** @vitest-environment jsdom */

import { expect, it } from 'vitest'
import { mount } from '@vue/test-utils'
import Info from '@components/admin/Info.vue'

it('shows the input', () => {
const wrapper = mount(Info, {
props: {
title: 'Title',
value: 'Value',
},
})

expect(wrapper.text()).toContain('Title')
expect(wrapper.text()).toContain('Value')
})

it('defaults to small style', () => {
const wrapper = mount(Info, {
props: {
title: 'Title',
value: 'Value',
},
})

expect(wrapper.find('.text-6xl').exists()).toBe(true)
expect(wrapper.find('.col-span-2').exists()).toBe(false)
})

it('can specify small style', () => {
const wrapper = mount(Info, {
props: {
title: 'Title',
value: 'Value',
style: 'small',
},
})

expect(wrapper.find('.text-6xl').exists()).toBe(true)
expect(wrapper.find('.col-span-2').exists()).toBe(false)
})

it('can be large', () => {
const wrapper = mount(Info, {
props: {
title: 'Title',
value: 'Value',
style: 'large',
},
})

expect(wrapper.find('.text-6xl').exists()).toBe(false)
expect(wrapper.find('.col-span-2').exists()).toBe(true)
})
80 changes: 36 additions & 44 deletions client/src/pages/AdminPage.vue
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
<script setup lang="ts">
import Info from '@client/components/admin/Info.vue'
import FormInput from '@client/components/form/FormInput.vue'
import { jsonHeaders } from '@client/data/headers'
import { ArrowPathIcon, LockClosedIcon } from '@heroicons/vue/24/solid'
import { ArrowPathIcon, LockClosedIcon, LockOpenIcon } from '@heroicons/vue/24/solid'
import { CacheWeeksOutput } from '@shared/dtos'
import { computed, ref } from 'vue'
Expand All @@ -23,8 +24,6 @@ const cacheWeeks = (fetchOnly: boolean = false) => {
})
.then(response => {
if([401, 403].includes(response.status)) {
console.error('Unauthorized to fetch week data: ', response.status, response.statusText)
return response.json()
}
Expand Down Expand Up @@ -76,7 +75,7 @@ const displayNewLastUpdated = computed(
class="flex flex-col space-y-4"
>
<button
class="flex items-center justify-center w-full px-4 py-2 mt-2 space-x-2 text-lg font-semibold text-white rounded-md h-14 md:w-auto bg-purp-dark hover:bg-purp-light focus:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:ring-purp-dark"
class="flex items-center justify-center w-full px-4 py-2 mt-2 space-x-2 text-lg font-semibold text-white rounded-md h-14 md:w-auto bg-purp-dark hover:bg-purp-light focus:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:ring-purp-dark disabled:opacity-75 disabled:hover:bg-purp-dark"
:disabled="cacheWeeksLoading"
@click="() => cacheWeeks()"
>
Expand All @@ -90,47 +89,37 @@ const displayNewLastUpdated = computed(
/>
</button>

<div
class="flex w-full"
>
<div class="flex w-full">
<div class="grid w-full grid-cols-2 gap-4">
<div class="flex flex-col items-center w-full p-3 rounded-md bg-brat-300">
<div class="font-semibold">
Weeks Cached
</div>
<div class="text-6xl">
{{ cacheWeeksOutput.updatedWeeks }}
</div>
</div>
<div class="flex flex-col items-center w-full p-3 rounded-md bg-brat-300">
<div class="font-semibold">
Movies Populated
</div>
<div class="text-6xl">
{{ cacheWeeksOutput.tmdbMoviesSynced.length }}
</div>
</div>
<div class="flex flex-col items-center w-full col-span-2 p-3 rounded-md bg-brat-300">
<div class="font-semibold">
Previous Last Updated
</div>
<div class="text-right">
{{ displayPreviousLastUpdated }}
</div>
</div>
<div class="flex flex-col items-center w-full col-span-2 p-3 rounded-md bg-brat-300">
<div class="font-semibold">
Current Last Updated
</div>
<div class="text-right">
{{ displayNewLastUpdated }}
</div>
</div>
<Info
title="Weeks Cached"
:value="cacheWeeksOutput.updatedWeeks.toString()"
/>

<Info
title="Movies Populated"
:value="cacheWeeksOutput.tmdbMoviesSynced.length.toString()"
/>

<Info
title="Previous Last Updated"
:value="displayPreviousLastUpdated"
:style="'large'"
/>

<Info
title="Current Last Updated"
:value="displayNewLastUpdated"
:style="'large'"
/>
</div>
</div>
</div>

<div v-else>
<div
v-else
class="flex flex-col space-y-4"
>
<FormInput
v-model="password"
name="password"
Expand All @@ -141,15 +130,18 @@ const displayNewLastUpdated = computed(
/>

<button
class="flex items-center justify-center w-full px-4 py-2 mt-2 space-x-2 text-lg font-semibold text-white rounded-md h-14 bg-purp-dark hover:bg-purp-light focus:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:ring-purp-dark"
class="flex items-center justify-center w-full px-4 py-2 space-x-2 text-lg font-semibold text-white rounded-md bg-purp-dark hover:bg-purp-light focus:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:ring-purp-dark disabled:opacity-75 disabled:hover:bg-purp-dark"
:disabled="cacheWeeksLoading"
data-testid="unlock-button"
@click="() => cacheWeeks(true)"
>
<span>Unlock</span>
<span>
{{ cacheWeeksLoading ? 'Unlocking' : 'Unlock' }}
</span>

<ArrowPathIcon
<LockOpenIcon
v-if="cacheWeeksLoading"
class="w-6 h-6 animate-spin"
class="w-6 h-6"
/>

<LockClosedIcon
Expand Down
88 changes: 88 additions & 0 deletions client/src/pages/__tests__/AdminPage.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
/** @vitest-environment jsdom */

import { beforeEach, describe, expect, it } from 'vitest'
import { mount, VueWrapper } from '@vue/test-utils'
import AdminPage from '@pages/AdminPage.vue'

let wrapper: VueWrapper

describe('unauthed page', () => {
it('shows password form', () => {
wrapper = mount(AdminPage)

expect(wrapper.byTestId('unlock-button').exists()).toBe(true)
expect(wrapper.byTestId('input-password').exists()).toBe(true)
})

it('does not show admin content', () => {
wrapper = mount(AdminPage)

expect(wrapper.text()).not.toContain('Sync Weeks')
})
})

describe('authentication problems', () => {
describe('401', () => {
beforeEach(async () => {
window.fetch.mockResponseOnce(JSON.stringify({
error: 'Something went wrong authenticating you',
}), {
status: 401,
})
wrapper = mount(AdminPage)
await wrapper.byTestId('input-password').setValue('password')
await wrapper.byTestId('unlock-button').trigger('click')
})

it('does not shows admin content', async () => {
expect(wrapper.text()).not.toContain('Sync Weeks')
expect(wrapper.text()).toContain('Something went wrong authenticating you')
})
})

describe('403', () => {
beforeEach(async () => {
window.fetch.mockResponseOnce(JSON.stringify({
error: 'Password incorrect',
}), {
status: 403,
})
wrapper = mount(AdminPage)
await wrapper.byTestId('input-password').setValue('password')
await wrapper.byTestId('unlock-button').trigger('click')
})

it('does not shows admin content', async () => {
expect(wrapper.text()).not.toContain('Sync Weeks')
expect(wrapper.text()).toContain('Password incorrect')
})
})
})

describe('correct password - logged in', () => {
beforeEach(async () => {
window.fetch.mockResponseOnce(JSON.stringify({
updatedWeeks: 15,
previousLastUpdated: '2021-01-01T00:00:00.000Z',
newLastUpdated: '2021-01-01T00:00:00.000Z',
tmdbMoviesSynced: Array.from({ length: 32 }, () => {}),
}))

wrapper = mount(AdminPage)
await wrapper.byTestId('input-password').setValue('password')
await wrapper.byTestId('unlock-button').trigger('click')
})

it('shows admin content', async () => {
expect(wrapper.text()).toContain('Sync Weeks')
})

it('shows updated weeks metadata', async () => {
expect(wrapper.text()).toContain('15')
expect(wrapper.text())
.toContain(new Date('2021-01-01T00:00:00.000Z').toLocaleString())
expect(wrapper.text())
.toContain(new Date('2021-01-01T00:00:00.000Z').toLocaleString())
expect(wrapper.text()).toContain('32')
})
})

0 comments on commit 5db5b2a

Please sign in to comment.