Skip to content

Commit

Permalink
feat(helper): ✨ support podcasts
Browse files Browse the repository at this point in the history
NOTE: this is a minimal implementation. Episode listing/data/runtime is not included
  • Loading branch information
djdembeck committed Sep 4, 2022
1 parent 7a4fd0f commit 9eaa00f
Show file tree
Hide file tree
Showing 4 changed files with 194 additions and 5 deletions.
7 changes: 5 additions & 2 deletions src/config/typing/audible.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,11 +47,13 @@ export interface AudibleProduct {
product: {
asin: string
authors: AuthorOnBook[]
available_codecs: Codecs[]
available_codecs?: Codecs[]
category_ladders: Categories[]
content_delivery_type: string
content_type: string
continuity?: string
editorial_reviews?: string[]
episode_count?: number
format_type: string
has_children: boolean
is_adult_product: boolean
Expand All @@ -61,6 +63,7 @@ export interface AudibleProduct {
language: string
merchandising_summary: string
narrators?: NarratorOnBook[]
new_episode_added_date?: string
product_images?: { [key: string]: string }
program_participation?: string
publication_datetime?: string
Expand All @@ -69,7 +72,7 @@ export interface AudibleProduct {
publisher_summary: string
rating: Ratings
release_date: string
runtime_length_min: number
runtime_length_min?: number
series?: AudibleSeries[]
sku?: string
sku_lite?: string
Expand Down
8 changes: 7 additions & 1 deletion src/helpers/books/audible/ApiHelper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,12 +48,18 @@ class ApiHelper {
// Get value of key
const value = this.inputJson[key as keyof typeof this.inputJson]

// Check if this looks like a podcast
const isPodcast = key === 'runtime_length_min' && this.inputJson.content_type === 'Podcast'

// Allow 0 as a valid value
const isNumberAndZero = typeof value === 'number' && value === 0

// Break on non valid value
let isValidKey = true
switch (isValidKey) {
case isPodcast:
isValidKey = true
break
case !keyExists:
isValidKey = false
message = `Required key '${key}' does not exist in Audible API response for ASIN ${this.asin}`
Expand Down Expand Up @@ -282,7 +288,7 @@ class ApiHelper {
rating: this.inputJson.rating.overall_distribution.display_average_rating.toString()
}),
releaseDate: this.getReleaseDate(),
runtimeLengthMin: this.inputJson.runtime_length_min,
runtimeLengthMin: this.inputJson.runtime_length_min ?? 0,
...(this.inputJson.series && {
seriesPrimary: series1,
...(series2 && {
Expand Down
144 changes: 143 additions & 1 deletion tests/datasets/audible/books/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ export function setupMinimalParsed(
publisherName: response.publisher_name,
summary: response.publisher_summary,
releaseDate: new Date(response.release_date),
runtimeLengthMin: response.runtime_length_min,
runtimeLengthMin: response.runtime_length_min ?? 0,
title: response.title,
...(response.series?.[0] && {
seriesPrimary: {
Expand Down Expand Up @@ -673,6 +673,148 @@ export const B07BS4RKGH = {
]
}

export const podcast: AudibleProduct = {
product: {
asin: 'B08JC5J5HR',
authors: [
{
name: 'Jackson Musker'
}
],
category_ladders: [
{
ladder: [
{
id: '18580606011',
name: 'Science Fiction & Fantasy'
},
{
id: '18580607011',
name: 'Fantasy'
}
],
root: 'Genres'
},
{
ladder: [
{
id: '18580606011',
name: 'Science Fiction & Fantasy'
},
{
id: '18580628011',
name: 'Science Fiction'
}
],
root: 'Genres'
}
],
content_delivery_type: 'PodcastParent',
content_type: 'Podcast',
continuity: 'serial',
episode_count: 12,
format_type: 'original_recording',
has_children: true,
is_adult_product: false,
is_listenable: false,
is_purchasability_suppressed: true,
issue_date: '2020-10-01',
language: 'english',
merchandising_summary:
'Wisecracking, marine biologist Bee Guerrero has signed up for the trip of a lifetime: a series of dives deep into the pitch-black waters of Saturn’s moon, Enceladus....',
narrators: [
{
name: 'Octavia Chavez-Richmond'
},
{
name: 'James Ludwig'
},
{
name: 'Pun Bandhu'
},
{
name: 'Lizan Mitchell'
},
{
name: 'a full cast'
}
],
new_episode_added_date: '2020-12-24T18:49:57.049Z',
product_images: {
'500': 'https://m.media-amazon.com/images/I/51izwaIIZ2L._SL500_.jpg',
'1024': 'https://m.media-amazon.com/images/I/9125JjSWeCL._SL1024_.jpg'
},
program_participation: 'Audible Original',
publication_datetime: '2020-10-01T07:00:00Z',
publisher_name: 'Audible Originals',
publisher_summary:
'<p>In this scripted Audible Original, wisecracking marine biologist and astronaut Bee Guerrero has signed up for the trip of a lifetime: a series of dives deep into the pitch-black waters of Saturn’s moon, Enceladus. </p> <p>Set in the near-future when global climate catastrophe has forced humans to search for solutions on new planets, <i>The Sea in the Sky</i> chronicles two astronauts’ journey, in what could be the final NASA-sponsored mission to space. In their search for life, Bee and Ty navigate uncharted waters, take on incredible risks and confront difficult truths about themselves. What will they find at the bottom of it all? </p> <p>At times epic and intimate, laugh-out-loud funny and achingly soulful, <i>The Sea in the Sky</i> plumbs the depths of science and faith, triumph and failure. The Audible Original drama is told via daily "dispatches" sent from the space shuttle back to Earth, together with original music and sound design, a never-before-heard space rap, and a full cast of actors. </p> <p>Dive into a world you need to hear to believe. </p> <p><i>Contains sensitive content. </i></p> <p>This original podcast is 12 episodes; please begin with the episode titled "Prologue". </p> <p>Note: this title contains fully immersive sound design and original composition. In order to enjoy the highest quality audio listening experience, please use headphones. If you choose to download this title, make sure it’s set to “High” in your settings.</p>',
rating: {
num_reviews: 517,
overall_distribution: {
average_rating: 4.489013184178985,
display_average_rating: '4.5',
display_stars: 4.5,
num_five_star_ratings: 1743,
num_four_star_ratings: 455,
num_one_star_ratings: 65,
num_ratings: 2503,
num_three_star_ratings: 156,
num_two_star_ratings: 84
},
performance_distribution: {
average_rating: 4.677432885906041,
display_average_rating: '4.7',
display_stars: 4.5,
num_five_star_ratings: 1909,
num_four_star_ratings: 304,
num_one_star_ratings: 40,
num_ratings: 2384,
num_three_star_ratings: 88,
num_two_star_ratings: 43
},
story_distribution: {
average_rating: 4.414799154334038,
display_average_rating: '4.4',
display_stars: 4.5,
num_five_star_ratings: 1568,
num_four_star_ratings: 462,
num_one_star_ratings: 82,
num_ratings: 2365,
num_three_star_ratings: 165,
num_two_star_ratings: 88
}
},
release_date: '2020-10-01',
sku: 'PD_30L0_000001',
sku_lite: 'PD_30L0_000001',
social_media_images: {
facebook:
'https://m.media-amazon.com/images/I/51izwaIIZ2L._SL10_UR1600,800_CR200,50,1200,630_CLa%7C1200,630%7C51izwaIIZ2L.jpg%7C0,0,1200,630+82,82,465,465_PJAdblSocialShare-Gradientoverlay-largeasin-0to70,TopLeft,0,0_PJAdblSocialShare-AudibleLogo-Large,TopLeft,600,270_OU01_ZBLISTENING%20ON,617,216,52,500,AudibleSansMd,30,255,255,255_PJAdblSocialShare-PodcastIcon-Small,TopLeft,1094,50.jpg',
twitter:
'https://m.media-amazon.com/images/I/51izwaIIZ2L._SL10_UR1600,800_CR200,50,1024,512_CLa%7C1024,512%7C51izwaIIZ2L.jpg%7C0,0,1024,512+67,67,376,376_PJAdblSocialShare-Gradientoverlay-twitter-largeasin-0to60,TopLeft,0,0_PJAdblSocialShare-AudibleLogo-Medium,TopLeft,490,223_OU01_ZBLISTENING%20ON,483,152,55,450,AudibleSansMd,32,255,255,255_PJAdblSocialShare-PodcastIcon-Small,TopLeft,929,45.jpg'
},
thesaurus_subject_keywords: [
'podcast_fiction',
'audible_original',
'podcast_science_fiction',
'podcast_show'
],
title: 'The Sea in the Sky'
},
response_groups: [
'product_desc',
'always-returned',
'product_extended_attrs',
'contributors',
'series',
'rating',
'category_ladders',
'media',
'product_attrs'
]
}

export const minimalB0036I54I6: Book = {
asin: 'B0036I54I6',
authors: [
Expand Down
40 changes: 39 additions & 1 deletion tests/helpers/books/audible/ApiHelper.test.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
/* eslint-disable @typescript-eslint/no-non-null-assertion */
import { AudibleProduct } from '#config/typing/audible'
import ApiHelper from '#helpers/books/audible/ApiHelper'
import { B07BS4RKGH, B017V4IM1G } from '#tests/datasets/audible/books/api'
import {
B07BS4RKGH,
B017V4IM1G,
podcast,
setupMinimalParsed
} from '#tests/datasets/audible/books/api'
import { apiResponse, parsedBook, parsedBookWithoutNarrators } from '#tests/datasets/helpers/books'

let asin: string
Expand Down Expand Up @@ -65,6 +70,34 @@ describe('ApiHelper should', () => {
test('parse response', async () => {
await expect(helper.parseResponse(apiResponse)).resolves.toEqual(parsedBook)
})

test('parse response with podcast', async () => {
const genres = [
{
asin: '18580606011',
name: 'Science Fiction & Fantasy',
type: 'genre'
},
{
asin: '18580607011',
name: 'Fantasy',
type: 'tag'
},
{
asin: '18580628011',
name: 'Science Fiction',
type: 'tag'
}
]
const image = 'https://m.media-amazon.com/images/I/9125JjSWeCL.jpg'
const minimalParsed = setupMinimalParsed(
podcast.product,
podcast.product.merchandising_summary,
image,
genres
)
await expect(helper.parseResponse(podcast)).resolves.toEqual(minimalParsed)
})
})

describe('ApiHelper edge cases should', () => {
Expand Down Expand Up @@ -141,6 +174,11 @@ describe('ApiHelper edge cases should', () => {
helper.inputJson!.asin = ''
expect(helper.hasRequiredKeys().isValid).toBe(false)
})

test('allow podcast to pass key check', () => {
helper.inputJson = podcast.product
expect(helper.hasRequiredKeys().isValid).toBe(true)
})
})

describe('ApiHelper should throw error when', () => {
Expand Down

0 comments on commit 9eaa00f

Please sign in to comment.