API to add recommended (popular) reads to a users library

This API is used in onboarding
This commit is contained in:
Jackson Harper
2022-05-24 12:05:35 -07:00
parent 8e30d793e0
commit 2b14d51ec6
10 changed files with 1486 additions and 0 deletions

View File

@ -16,6 +16,24 @@ export type Scalars = {
Date: any;
};
export type AddPopularReadError = {
__typename?: 'AddPopularReadError';
errorCodes: Array<AddPopularReadErrorCode>;
};
export enum AddPopularReadErrorCode {
BadRequest = 'BAD_REQUEST',
NotFound = 'NOT_FOUND',
Unauthorized = 'UNAUTHORIZED'
}
export type AddPopularReadResult = AddPopularReadError | AddPopularReadSuccess;
export type AddPopularReadSuccess = {
__typename?: 'AddPopularReadSuccess';
pageId: Scalars['String'];
};
export type ArchiveLinkError = {
__typename?: 'ArchiveLinkError';
errorCodes: Array<ArchiveLinkErrorCode>;
@ -783,6 +801,7 @@ export type MergeHighlightSuccess = {
export type Mutation = {
__typename?: 'Mutation';
addPopularRead: AddPopularReadResult;
createArticle: CreateArticleResult;
createArticleSavingRequest: CreateArticleSavingRequestResult;
createHighlight: CreateHighlightResult;
@ -832,6 +851,11 @@ export type Mutation = {
};
export type MutationAddPopularReadArgs = {
name: Scalars['String'];
};
export type MutationCreateArticleArgs = {
input: CreateArticleInput;
};
@ -2115,6 +2139,10 @@ export type DirectiveResolverFn<TResult = {}, TParent = {}, TContext = {}, TArgs
/** Mapping between all available schema types and the resolvers types */
export type ResolversTypes = {
AddPopularReadError: ResolverTypeWrapper<AddPopularReadError>;
AddPopularReadErrorCode: AddPopularReadErrorCode;
AddPopularReadResult: ResolversTypes['AddPopularReadError'] | ResolversTypes['AddPopularReadSuccess'];
AddPopularReadSuccess: ResolverTypeWrapper<AddPopularReadSuccess>;
ArchiveLinkError: ResolverTypeWrapper<ArchiveLinkError>;
ArchiveLinkErrorCode: ArchiveLinkErrorCode;
ArchiveLinkInput: ArchiveLinkInput;
@ -2429,6 +2457,9 @@ export type ResolversTypes = {
/** Mapping between all available schema types and the resolvers parents */
export type ResolversParentTypes = {
AddPopularReadError: AddPopularReadError;
AddPopularReadResult: ResolversParentTypes['AddPopularReadError'] | ResolversParentTypes['AddPopularReadSuccess'];
AddPopularReadSuccess: AddPopularReadSuccess;
ArchiveLinkError: ArchiveLinkError;
ArchiveLinkInput: ArchiveLinkInput;
ArchiveLinkResult: ResolversParentTypes['ArchiveLinkError'] | ResolversParentTypes['ArchiveLinkSuccess'];
@ -2684,6 +2715,20 @@ export type SanitizeDirectiveArgs = {
export type SanitizeDirectiveResolver<Result, Parent, ContextType = ResolverContext, Args = SanitizeDirectiveArgs> = DirectiveResolverFn<Result, Parent, ContextType, Args>;
export type AddPopularReadErrorResolvers<ContextType = ResolverContext, ParentType extends ResolversParentTypes['AddPopularReadError'] = ResolversParentTypes['AddPopularReadError']> = {
errorCodes?: Resolver<Array<ResolversTypes['AddPopularReadErrorCode']>, ParentType, ContextType>;
__isTypeOf?: IsTypeOfResolverFn<ParentType, ContextType>;
};
export type AddPopularReadResultResolvers<ContextType = ResolverContext, ParentType extends ResolversParentTypes['AddPopularReadResult'] = ResolversParentTypes['AddPopularReadResult']> = {
__resolveType: TypeResolveFn<'AddPopularReadError' | 'AddPopularReadSuccess', ParentType, ContextType>;
};
export type AddPopularReadSuccessResolvers<ContextType = ResolverContext, ParentType extends ResolversParentTypes['AddPopularReadSuccess'] = ResolversParentTypes['AddPopularReadSuccess']> = {
pageId?: Resolver<ResolversTypes['String'], ParentType, ContextType>;
__isTypeOf?: IsTypeOfResolverFn<ParentType, ContextType>;
};
export type ArchiveLinkErrorResolvers<ContextType = ResolverContext, ParentType extends ResolversParentTypes['ArchiveLinkError'] = ResolversParentTypes['ArchiveLinkError']> = {
errorCodes?: Resolver<Array<ResolversTypes['ArchiveLinkErrorCode']>, ParentType, ContextType>;
message?: Resolver<ResolversTypes['String'], ParentType, ContextType>;
@ -3237,6 +3282,7 @@ export type MergeHighlightSuccessResolvers<ContextType = ResolverContext, Parent
};
export type MutationResolvers<ContextType = ResolverContext, ParentType extends ResolversParentTypes['Mutation'] = ResolversParentTypes['Mutation']> = {
addPopularRead?: Resolver<ResolversTypes['AddPopularReadResult'], ParentType, ContextType, RequireFields<MutationAddPopularReadArgs, 'name'>>;
createArticle?: Resolver<ResolversTypes['CreateArticleResult'], ParentType, ContextType, RequireFields<MutationCreateArticleArgs, 'input'>>;
createArticleSavingRequest?: Resolver<ResolversTypes['CreateArticleSavingRequestResult'], ParentType, ContextType, RequireFields<MutationCreateArticleSavingRequestArgs, 'input'>>;
createHighlight?: Resolver<ResolversTypes['CreateHighlightResult'], ParentType, ContextType, RequireFields<MutationCreateHighlightArgs, 'input'>>;
@ -3878,6 +3924,9 @@ export type UserSuccessResolvers<ContextType = ResolverContext, ParentType exten
};
export type Resolvers<ContextType = ResolverContext> = {
AddPopularReadError?: AddPopularReadErrorResolvers<ContextType>;
AddPopularReadResult?: AddPopularReadResultResolvers<ContextType>;
AddPopularReadSuccess?: AddPopularReadSuccessResolvers<ContextType>;
ArchiveLinkError?: ArchiveLinkErrorResolvers<ContextType>;
ArchiveLinkResult?: ArchiveLinkResultResolvers<ContextType>;
ArchiveLinkSuccess?: ArchiveLinkSuccessResolvers<ContextType>;

View File

@ -1,5 +1,21 @@
directive @sanitize(allowedTags: [String], maxLength: Int, pattern: String) on INPUT_FIELD_DEFINITION
type AddPopularReadError {
errorCodes: [AddPopularReadErrorCode!]!
}
enum AddPopularReadErrorCode {
BAD_REQUEST
NOT_FOUND
UNAUTHORIZED
}
union AddPopularReadResult = AddPopularReadError | AddPopularReadSuccess
type AddPopularReadSuccess {
pageId: String!
}
type ArchiveLinkError {
errorCodes: [ArchiveLinkErrorCode!]!
message: String!
@ -693,6 +709,7 @@ type MergeHighlightSuccess {
}
type Mutation {
addPopularRead(name: String!): AddPopularReadResult!
createArticle(input: CreateArticleInput!): CreateArticleResult!
createArticleSavingRequest(input: CreateArticleSavingRequestInput!): CreateArticleSavingRequestResult!
createHighlight(input: CreateHighlightInput!): CreateHighlightResult!

View File

@ -78,6 +78,7 @@ import {
uploadFileRequestResolver,
validateUsernameResolver,
updatePageResolver,
addPopularReadResolver,
} from './index'
import { getShareInfoForArticle } from '../datalayer/links/share_info'
import {
@ -149,6 +150,7 @@ export const functionResolvers = {
unsubscribe: unsubscribeResolver,
updatePage: updatePageResolver,
subscribe: subscribeResolver,
addPopularRead: addPopularReadResolver,
},
Query: {
me: getMeUserResolver,
@ -560,4 +562,5 @@ export const functionResolvers = {
...resultResolveTypeResolver('UpdateLabel'),
...resultResolveTypeResolver('UpdatePage'),
...resultResolveTypeResolver('Subscribe'),
...resultResolveTypeResolver('AddPopularRead'),
}

View File

@ -16,3 +16,4 @@ export * from './user_device_tokens'
export * from './labels'
export * from './subscriptions'
export * from './update'
export * from './popular_reads'

View File

@ -0,0 +1,45 @@
import {
MutationAddPopularReadArgs,
AddPopularReadError,
AddPopularReadErrorCode,
AddPopularReadSuccess,
} from '../../generated/graphql'
import { authorized, userDataToUser } from '../../utils/helpers'
import { analytics } from '../../utils/analytics'
import { addPopularRead } from '../../services/popular_reads'
import { env } from '../../env'
export const addPopularReadResolver = authorized<
AddPopularReadSuccess,
AddPopularReadError,
MutationAddPopularReadArgs
>(async (_, { name }, ctx) => {
console.log('************************ addPopularRead ************************')
const {
models,
claims: { uid },
} = ctx
analytics.track({
userId: uid,
event: 'popular_read_added',
properties: {
name: name,
env: env.server.apiEnv,
},
})
const user = userDataToUser(await models.user.get(uid))
if (!user) {
return { errorCodes: [AddPopularReadErrorCode.Unauthorized] }
}
const pageId = await addPopularRead(uid, name)
if (!pageId) {
return { errorCodes: [AddPopularReadErrorCode.NotFound] }
}
return {
pageId,
}
})

View File

@ -1552,6 +1552,22 @@ const schema = gql`
ALREADY_SUBSCRIBED
}
union AddPopularReadResult = AddPopularReadSuccess | AddPopularReadError
type AddPopularReadSuccess {
pageId: String!
}
type AddPopularReadError {
errorCodes: [AddPopularReadErrorCode!]!
}
enum AddPopularReadErrorCode {
UNAUTHORIZED
BAD_REQUEST
NOT_FOUND
}
# Mutations
type Mutation {
googleLogin(input: GoogleLoginInput!): LoginResult!
@ -1616,6 +1632,7 @@ const schema = gql`
generateApiKey(input: GenerateApiKeyInput!): GenerateApiKeyResult!
unsubscribe(name: String!): UnsubscribeResult!
subscribe(name: String!): SubscribeResult!
addPopularRead(name: String!): AddPopularReadResult!
}
# FIXME: remove sort from feedArticles after all cached tabs are closed

View File

@ -0,0 +1,108 @@
import { createPage } from '../elastic/pages'
import { createPubSubClient } from '../datalayer/pubsub'
import { ArticleSavingRequestStatus, Page, PageContext } from '../elastic/types'
import { PageType } from '../generated/graphql'
import { generateSlug, stringToHash } from '../utils/helpers'
import { readFileSync } from 'fs';
import path from 'path'
type PopularRead = {
url: string
title: string
author: string
description: string
previewImage: string
publishedAt: Date
siteName: string
content: string
originalHtml: string
}
const popularRead = (key: string): PopularRead | undefined => {
const metadata = popularReads.find((pr) => pr.key === key)
if (!metadata) {
return undefined
}
const content = readFileSync(path.resolve(__dirname, `popular_reads/${key}-content.html`), 'utf8')
const originalHtml = readFileSync(path.resolve(__dirname, `./popular_reads/${key}-original.html`), 'utf8')
if (!content || !originalHtml) {
return undefined
}
return {
...metadata,
content,
originalHtml,
}
}
export const addPopularRead = async (
userId: string,
name: string
): Promise<string | undefined> => {
const ctx: PageContext = {
pubsub: createPubSubClient(),
refresh: true,
uid: userId,
}
const pr = popularRead(name)
if (!pr) {
return undefined
}
const saveTime = new Date()
const slug = generateSlug(pr.title)
const articleToSave: Page = {
id: '',
slug: slug,
userId: userId,
content: pr.content,
originalHtml: pr.originalHtml,
description: pr.description,
title: pr.title,
author: pr.author,
url: pr.url,
pageType: PageType.Article,
hash: stringToHash(pr.content),
image: pr.previewImage,
publishedAt: pr.publishedAt,
savedAt: saveTime,
createdAt: saveTime,
siteName: pr.siteName,
readingProgressPercent: 0,
readingProgressAnchorIndex: 0,
state: ArticleSavingRequestStatus.Succeeded,
}
const pageId = await createPage(articleToSave, ctx)
return pageId
}
const popularReads = [
{
key: 'omnivore_get_started',
url: 'https://blog.omnivore.app/p/getting-started-with-omnivore',
title: 'Getting Started with Omnivore',
author: 'The Omnivore Team',
description: 'Get the most out of Omnivore by learning how to use it.',
previewImage: 'https://proxy-prod.omnivore-image-cache.app/88x88,sBp_gMyIp8Y4Mje8lzL39vzrBQg5m9KbprssrGjCbbHw/https://substackcdn.com/image/fetch/w_1200,h_600,c_limit,f_jpg,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F658efff4-341a-4720-8cf6-9b2bdbedfaa7_800x668.gif',
publishedAt: new Date('2021-10-13'),
siteName: 'Omnivore Blog',
},
{
key: 'omnivire_organize',
url: 'https://blog.omnivore.app/p/organize-your-omnivore-library-with',
title: 'Organize your Omnivore library with labels',
author: 'The Omnivore Team',
description: 'Use labels to organize your Omnivore library.',
previewImage: 'https://proxy-prod.omnivore-image-cache.app/88x88,sSLRtT7zJbaNFEUbqDe9jbr3nloPsdjaqQXUqISk_x7E/https://substackcdn.com/image/fetch/w_1200,h_600,c_limit,f_jpg,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Fa4ec9f3c-baef-464b-8d3a-0b8a384874d3_960x711.gif',
publishedAt: new Date('2022-04-18'),
siteName: 'Omnivore Blog',
}
]

View File

@ -0,0 +1,118 @@
<DIV class="page" id="readability-page-1">
<div>
<h3> Learn the best ways to save links with Omnivore </h3>
</div>
<div dir="auto">
<p> Omnivore is a home for everything you read. We keep it safe, organized, and easy to share. </p>
<p> When you start using Omnivore, it is important to figure out the best way to save content to your library. </p>
<h2>
<strong>Saving from your iPhone</strong>
</h2>
<p> If you are using an iPhone or iPad, the best way to save links is by installing the iOS app. You can find the iOS app here: </p>
<p>
<a href="https://omnivore.app/install/ios" rel="">https://omnivore.app/install/ios</a>
</p>
<p> With the iOS Share extension installed, you can save links from Safari or any other app that supports sharing links. </p>
<div>
<figure>
<a target="_blank" rel="nofollow" href="https://substackcdn.com/image/fetch/f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Fb116ac39-34b8-4868-a2b0-b20c79f610c3_256x419.gif">
<picture>
<source type="image/webp" srcset="https://substackcdn.com/image/fetch/w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Fb116ac39-34b8-4868-a2b0-b20c79f610c3_256x419.gif 424w, https://substackcdn.com/image/fetch/w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Fb116ac39-34b8-4868-a2b0-b20c79f610c3_256x419.gif 848w, https://substackcdn.com/image/fetch/w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Fb116ac39-34b8-4868-a2b0-b20c79f610c3_256x419.gif 1272w, https://substackcdn.com/image/fetch/w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Fb116ac39-34b8-4868-a2b0-b20c79f610c3_256x419.gif 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Fb116ac39-34b8-4868-a2b0-b20c79f610c3_256x419.gif" width="320" height="523.75" data-attrs="{&quot;src&quot;:&quot;https://bucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com/public/images/b116ac39-34b8-4868-a2b0-b20c79f610c3_256x419.gif&quot;,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:419,&quot;width&quot;:256,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:275502,&quot;alt&quot;:&quot;Saving with the Omnivore iOS Share Extension&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/gif&quot;,&quot;href&quot;:null}" alt="Saving with the Omnivore iOS Share Extension" title="Saving with the Omnivore iOS Share Extension" srcset="https://substackcdn.com/image/fetch/w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Fb116ac39-34b8-4868-a2b0-b20c79f610c3_256x419.gif 424w, https://substackcdn.com/image/fetch/w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Fb116ac39-34b8-4868-a2b0-b20c79f610c3_256x419.gif 848w, https://substackcdn.com/image/fetch/w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Fb116ac39-34b8-4868-a2b0-b20c79f610c3_256x419.gif 1272w, https://substackcdn.com/image/fetch/w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Fb116ac39-34b8-4868-a2b0-b20c79f610c3_256x419.gif 1456w" sizes="100vw">
</picture>
</a>
<figcaption> Saving with the Omnivore iOS Share Extension </figcaption>
</figure>
</div>
<p> When you first install the app, Omnivore might not show up in your list of share targets. To make sure Omnivore is easy to access, scroll to the far right, click More, and add Omnivore. </p>
<h2> Saving from your Android Device </h2>
<p> If you are using an Android device you can install the Omnivore Progressive Web App. After logging in to Omnivore in Chrome you should see an “Install Omnivore” option. Most Android versions display this at the bottom of the screen. </p>
<div>
<figure>
<a target="_blank" rel="nofollow" href="https://substackcdn.com/image/fetch/f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F4255167b-bc82-4187-a043-3150cbbdc17d_320x152.png">
<picture>
<source type="image/webp" srcset="https://substackcdn.com/image/fetch/w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F4255167b-bc82-4187-a043-3150cbbdc17d_320x152.png 424w, https://substackcdn.com/image/fetch/w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F4255167b-bc82-4187-a043-3150cbbdc17d_320x152.png 848w, https://substackcdn.com/image/fetch/w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F4255167b-bc82-4187-a043-3150cbbdc17d_320x152.png 1272w, https://substackcdn.com/image/fetch/w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F4255167b-bc82-4187-a043-3150cbbdc17d_320x152.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F4255167b-bc82-4187-a043-3150cbbdc17d_320x152.png" width="320" height="152" data-attrs="{&quot;src&quot;:&quot;https://bucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com/public/images/4255167b-bc82-4187-a043-3150cbbdc17d_320x152.png&quot;,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:152,&quot;width&quot;:320,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:15668,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null}" alt="" srcset="https://substackcdn.com/image/fetch/w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F4255167b-bc82-4187-a043-3150cbbdc17d_320x152.png 424w, https://substackcdn.com/image/fetch/w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F4255167b-bc82-4187-a043-3150cbbdc17d_320x152.png 848w, https://substackcdn.com/image/fetch/w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F4255167b-bc82-4187-a043-3150cbbdc17d_320x152.png 1272w, https://substackcdn.com/image/fetch/w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F4255167b-bc82-4187-a043-3150cbbdc17d_320x152.png 1456w" sizes="100vw">
</picture>
</a>
</figure>
</div>
<p> After installing Omnivore as a Progressive Web App it will be displayed in your Sharing Menu on Chrome. </p>
<div>
<figure>
<a target="_blank" rel="nofollow" href="https://substackcdn.com/image/fetch/f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Ff382aca6-3fbf-4a0c-a69e-8270c1554e24_320x693.png">
<picture>
<source type="image/webp" srcset="https://substackcdn.com/image/fetch/w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Ff382aca6-3fbf-4a0c-a69e-8270c1554e24_320x693.png 424w, https://substackcdn.com/image/fetch/w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Ff382aca6-3fbf-4a0c-a69e-8270c1554e24_320x693.png 848w, https://substackcdn.com/image/fetch/w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Ff382aca6-3fbf-4a0c-a69e-8270c1554e24_320x693.png 1272w, https://substackcdn.com/image/fetch/w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Ff382aca6-3fbf-4a0c-a69e-8270c1554e24_320x693.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Ff382aca6-3fbf-4a0c-a69e-8270c1554e24_320x693.png" width="320" height="693" data-attrs="{&quot;src&quot;:&quot;https://bucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com/public/images/f382aca6-3fbf-4a0c-a69e-8270c1554e24_320x693.png&quot;,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:693,&quot;width&quot;:320,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:43062,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null}" alt="" srcset="https://substackcdn.com/image/fetch/w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Ff382aca6-3fbf-4a0c-a69e-8270c1554e24_320x693.png 424w, https://substackcdn.com/image/fetch/w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Ff382aca6-3fbf-4a0c-a69e-8270c1554e24_320x693.png 848w, https://substackcdn.com/image/fetch/w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Ff382aca6-3fbf-4a0c-a69e-8270c1554e24_320x693.png 1272w, https://substackcdn.com/image/fetch/w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Ff382aca6-3fbf-4a0c-a69e-8270c1554e24_320x693.png 1456w" sizes="100vw">
</picture>
</a>
</figure>
</div>
<h2>
<strong>Saving from your computer</strong>
</h2>
<p> If you are saving from a computer, you will need to install the Omnivore extension for the web browser(s) you use. </p>
<p> The browser extensions are available here: </p>
<ul>
<li>
<p> Chrome: <a href="https://omnivore.app/install/chrome" rel="">https://omnivore.app/install/chrome</a>
</p>
</li>
<li>
<p> Edge: <a href="https://omnivore.app/install/edge" rel="">https://omnivore.app/install/edge</a>
</p>
</li>
<li>
<p> Firefox: <a href="https://omnivore.app/install/firefox" rel="">https://omnivore.app/install/firefox</a>
</p>
</li>
<li>
<p> Safari: https://omnivore.app/install/safari </p>
</li>
</ul>
<p> With the browser extension(s) of your choice installed, you can tap the Omnivore button on any page to save your link. </p>
<div>
<figure>
<a target="_blank" rel="nofollow" href="https://substackcdn.com/image/fetch/f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F658efff4-341a-4720-8cf6-9b2bdbedfaa7_800x668.gif">
<picture>
<source type="image/webp" srcset="https://substackcdn.com/image/fetch/w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F658efff4-341a-4720-8cf6-9b2bdbedfaa7_800x668.gif 424w, https://substackcdn.com/image/fetch/w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F658efff4-341a-4720-8cf6-9b2bdbedfaa7_800x668.gif 848w, https://substackcdn.com/image/fetch/w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F658efff4-341a-4720-8cf6-9b2bdbedfaa7_800x668.gif 1272w, https://substackcdn.com/image/fetch/w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F658efff4-341a-4720-8cf6-9b2bdbedfaa7_800x668.gif 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F658efff4-341a-4720-8cf6-9b2bdbedfaa7_800x668.gif" width="800" height="668" data-attrs="{&quot;src&quot;:&quot;https://bucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com/public/images/658efff4-341a-4720-8cf6-9b2bdbedfaa7_800x668.gif&quot;,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:668,&quot;width&quot;:800,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:148745,&quot;alt&quot;:&quot;Saving with the Omnivore Browser Extension&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/gif&quot;,&quot;href&quot;:null}" alt="Saving with the Omnivore Browser Extension" title="Saving with the Omnivore Browser Extension" srcset="https://substackcdn.com/image/fetch/w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F658efff4-341a-4720-8cf6-9b2bdbedfaa7_800x668.gif 424w, https://substackcdn.com/image/fetch/w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F658efff4-341a-4720-8cf6-9b2bdbedfaa7_800x668.gif 848w, https://substackcdn.com/image/fetch/w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F658efff4-341a-4720-8cf6-9b2bdbedfaa7_800x668.gif 1272w, https://substackcdn.com/image/fetch/w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F658efff4-341a-4720-8cf6-9b2bdbedfaa7_800x668.gif 1456w" sizes="100vw">
</picture>
</a>
<figcaption> Saving with the Omnivore Browser Extension </figcaption>
</figure>
</div>
<h2>
<strong>Saving PDFs with the Mac App</strong>
</h2>
<p> https://omnivore.app/install/mac </p>
<p> With the MacOS App installed you can upload PDFs from your computer to your Omnivore library by right-clicking and sharing to Omnivore. </p>
<div>
<figure>
<a target="_blank" rel="nofollow" href="https://substackcdn.com/image/fetch/f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F598e774d-1c20-43e3-bccf-be875f7b6616_1400x955.png">
<picture>
<source type="image/webp" srcset="https://substackcdn.com/image/fetch/w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F598e774d-1c20-43e3-bccf-be875f7b6616_1400x955.png 424w, https://substackcdn.com/image/fetch/w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F598e774d-1c20-43e3-bccf-be875f7b6616_1400x955.png 848w, https://substackcdn.com/image/fetch/w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F598e774d-1c20-43e3-bccf-be875f7b6616_1400x955.png 1272w, https://substackcdn.com/image/fetch/w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F598e774d-1c20-43e3-bccf-be875f7b6616_1400x955.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F598e774d-1c20-43e3-bccf-be875f7b6616_1400x955.png" width="1400" height="955" data-attrs="{&quot;src&quot;:&quot;https://bucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com/public/images/598e774d-1c20-43e3-bccf-be875f7b6616_1400x955.png&quot;,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:955,&quot;width&quot;:1400,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:297887,&quot;alt&quot;:&quot;Sharing a PDF with Omnivore&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null}" alt="Sharing a PDF with Omnivore" title="Sharing a PDF with Omnivore" srcset="https://substackcdn.com/image/fetch/w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F598e774d-1c20-43e3-bccf-be875f7b6616_1400x955.png 424w, https://substackcdn.com/image/fetch/w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F598e774d-1c20-43e3-bccf-be875f7b6616_1400x955.png 848w, https://substackcdn.com/image/fetch/w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F598e774d-1c20-43e3-bccf-be875f7b6616_1400x955.png 1272w, https://substackcdn.com/image/fetch/w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F598e774d-1c20-43e3-bccf-be875f7b6616_1400x955.png 1456w" sizes="100vw">
</picture>
</a>
<figcaption> Sharing a PDF with Omnivore </figcaption>
</figure>
</div>
<p> You can enable sharing from Finder on the Mac in the Extensions section of System Preferences. </p>
<div>
<figure>
<a target="_blank" rel="nofollow" href="https://substackcdn.com/image/fetch/f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Fe109c534-a502-49cb-a245-3deba005fe84_960x709.gif">
<picture>
<source type="image/webp" srcset="https://substackcdn.com/image/fetch/w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Fe109c534-a502-49cb-a245-3deba005fe84_960x709.gif 424w, https://substackcdn.com/image/fetch/w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Fe109c534-a502-49cb-a245-3deba005fe84_960x709.gif 848w, https://substackcdn.com/image/fetch/w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Fe109c534-a502-49cb-a245-3deba005fe84_960x709.gif 1272w, https://substackcdn.com/image/fetch/w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Fe109c534-a502-49cb-a245-3deba005fe84_960x709.gif 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Fe109c534-a502-49cb-a245-3deba005fe84_960x709.gif" width="960" height="709" data-attrs="{&quot;src&quot;:&quot;https://bucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com/public/images/e109c534-a502-49cb-a245-3deba005fe84_960x709.gif&quot;,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:709,&quot;width&quot;:960,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:2973845,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null}" alt="" srcset="https://substackcdn.com/image/fetch/w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Fe109c534-a502-49cb-a245-3deba005fe84_960x709.gif 424w, https://substackcdn.com/image/fetch/w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Fe109c534-a502-49cb-a245-3deba005fe84_960x709.gif 848w, https://substackcdn.com/image/fetch/w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Fe109c534-a502-49cb-a245-3deba005fe84_960x709.gif 1272w, https://substackcdn.com/image/fetch/w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Fe109c534-a502-49cb-a245-3deba005fe84_960x709.gif 1456w" sizes="100vw">
</picture>
</a>
</figure>
</div>
<h2> Using Omnivore </h2>
<p> We created a quick tour of Omnivore to get your started with all the other features. This video demonstrates search, archiving, and keyboard commands in the library and sharing highlights from the reader. </p>
<div>
<figure>
<a target="_blank" rel="nofollow" href="https://www.loom.com/share/a9afdd040dd349e28317430e1a178acc">
<picture>
<source type="image/webp" srcset="https://substackcdn.com/image/fetch/w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F59cc33d5-9a9f-4e40-b4a3-c7a399cc293f_576x360.gif 424w, https://substackcdn.com/image/fetch/w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F59cc33d5-9a9f-4e40-b4a3-c7a399cc293f_576x360.gif 848w, https://substackcdn.com/image/fetch/w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F59cc33d5-9a9f-4e40-b4a3-c7a399cc293f_576x360.gif 1272w, https://substackcdn.com/image/fetch/w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F59cc33d5-9a9f-4e40-b4a3-c7a399cc293f_576x360.gif 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F59cc33d5-9a9f-4e40-b4a3-c7a399cc293f_576x360.gif" width="576" height="360" data-attrs="{&quot;src&quot;:&quot;https://bucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com/public/images/59cc33d5-9a9f-4e40-b4a3-c7a399cc293f_576x360.gif&quot;,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:360,&quot;width&quot;:576,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:71790,&quot;alt&quot;:&quot;Screenshot of video demonstrating Omnivore&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/gif&quot;,&quot;href&quot;:&quot;https://www.loom.com/share/a9afdd040dd349e28317430e1a178acc&quot;}" alt="Screenshot of video demonstrating Omnivore" title="Screenshot of video demonstrating Omnivore" srcset="https://substackcdn.com/image/fetch/w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F59cc33d5-9a9f-4e40-b4a3-c7a399cc293f_576x360.gif 424w, https://substackcdn.com/image/fetch/w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F59cc33d5-9a9f-4e40-b4a3-c7a399cc293f_576x360.gif 848w, https://substackcdn.com/image/fetch/w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F59cc33d5-9a9f-4e40-b4a3-c7a399cc293f_576x360.gif 1272w, https://substackcdn.com/image/fetch/w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F59cc33d5-9a9f-4e40-b4a3-c7a399cc293f_576x360.gif 1456w" sizes="100vw">
</picture>
</a>
</figure>
</div>
</div>
</DIV>

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,61 @@
import { createTestSubscription, createTestUser, deleteTestUser } from '../db'
import { graphqlRequest, request } from '../util'
import { Subscription } from '../../src/entity/subscription'
import { expect } from 'chai'
import 'mocha'
import { User } from '../../src/entity/user'
import { getPageById, getPageByParam } from '../../src/elastic/pages'
describe('PopularReads API', () => {
const username = 'fakeUser'
let user: User
let authToken: string
const addPopularReadQuery = (readName: string) => {
return `
mutation {
addPopularRead(name: "${readName}") {
... on AddPopularReadSuccess {
pageId
}
... on AddPopularReadError {
errorCodes
}
}
}
`
}
before(async () => {
// create test user and login
user = await createTestUser(username)
const res = await request
.post('/local/debug/fake-user-login')
.send({ fakeEmail: user.email })
authToken = res.body.authToken
})
after(async () => {
// clean up
await deleteTestUser(username)
})
describe('addPopularRead', () => {
it('should add a new article if the readName is valid', async () => {
const readName = 'omnivore_get_started'
const res = await graphqlRequest(addPopularReadQuery(readName), authToken).expect(200)
expect(res.body.data.addPopularRead.pageId).to.be
const page = await getPageByParam({ userId: user.id, _id: res.body.data.addPopularRead.pageId })
expect(page?.url).to.eq('https://blog.omnivore.app/p/getting-started-with-omnivore')
})
it('responds status code 500 when invalid user', async () => {
const invalidAuthToken = 'Fake token'
const readName = 'omnivore_get_started'
return graphqlRequest(addPopularReadQuery(readName), invalidAuthToken).expect(500)
})
})
})