Skip to content

Commit

Permalink
Accept empty input to SubredditConfig constructor (#66)
Browse files Browse the repository at this point in the history
Co-authored-by: Erin <github@eritbh.me>
  • Loading branch information
fsvreddit and eritbh authored Oct 31, 2024
1 parent 3859e96 commit ea0b3f8
Show file tree
Hide file tree
Showing 4 changed files with 73 additions and 6 deletions.
32 changes: 32 additions & 0 deletions src/classes/SubredditConfig.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,36 @@
import test from 'ava';
import {DEFAULT_CONFIG} from '../helpers/config';
import {SubredditConfig} from './SubredditConfig';

test('constructor: accept empty input', t => {
t.assert(
new SubredditConfig() instanceof SubredditConfig,
'passing nothing to SubredditConfig constructor should return a SubredditConfig instance',
);

t.assert(
new SubredditConfig('') instanceof SubredditConfig,
'passing empty string to SubredditConfig constructor should return a SubredditConfig instance',
);
});

test('constructor: results of passing in nothing and empty input are identical', t => {
const configFromNothing = new SubredditConfig();
const configFromEmpty = new SubredditConfig('');

t.deepEqual(
configFromNothing.toJSON(),
configFromEmpty.toJSON(),
'SubredditConfig initiated with nothing vs empty should be identical',
);
});

test('constructor: on empty input, the default config is returned', t => {
const config = new SubredditConfig();
const configAsJson = config.toJSON();

t.deepEqual(configAsJson, DEFAULT_CONFIG, "SubredditConfig initiated with nothing should return default config");
});

test.todo('getAllNoteTypes');
test.todo('getNoteType');
Expand Down
10 changes: 8 additions & 2 deletions src/classes/SubredditConfig.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import {
DEFAULT_CONFIG,
DEFAULT_USERNOTE_TYPES,
migrateConfigToLatestSchema,
} from '../helpers/config';
Expand All @@ -15,8 +16,13 @@ import type {Usernote} from '../types/Usernote';
export class SubredditConfig {
private data: RawSubredditConfig;

constructor (jsonString: string) {
this.data = migrateConfigToLatestSchema(JSON.parse(jsonString));
constructor (jsonString?: string) {
if (jsonString) {
this.data = migrateConfigToLatestSchema(JSON.parse(jsonString));
} else {
// TODO: the default config value isn't actually typed correctly, this needs to be cleaned up eventually
this.data = DEFAULT_CONFIG as unknown as RawSubredditConfig;
}
}

/** Returns all usernote types. */
Expand Down
23 changes: 19 additions & 4 deletions src/classes/ToolboxClient.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import {RedditAPIClient} from '@devvit/public-api';
import {RedditAPIClient, WikiPage} from '@devvit/public-api';
import {Usernote, UsernoteInit} from '../types/Usernote';
import {SubredditConfig} from './SubredditConfig';
import {Usernotes} from './Usernotes';
Expand Down Expand Up @@ -140,9 +140,24 @@ export class ToolboxClient {
await this.writeUsernotes(subreddit, notes, reason);
}

/** */
/**
* Retrieves toolbox configuration for a subreddit.
* @param subreddit Name of the subreddit to retrieve config for
*/
async getConfig (subreddit: string) {
const page = await this.reddit.getWikiPage(subreddit, TB_CONFIG_PAGE);
return new SubredditConfig(page.content);
let page: WikiPage | undefined;
try {
page = await this.reddit.getWikiPage(subreddit, TB_CONFIG_PAGE);
} catch (error) {
// Devvit throws an error when page is not present, but also
// sometimes for other reasons. Check if the page actually
// exists; if it doesn't we'll use the default config, but if it
// does then something else is wrong and we'll rethrow the error.
const allPages = await this.reddit.getWikiPages(subreddit);
if (allPages.includes(TB_CONFIG_PAGE)) {
throw error;
}
}
return new SubredditConfig(page?.content);
}
}
14 changes: 14 additions & 0 deletions src/helpers/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,20 @@ export const DEFAULT_USERNOTE_TYPES: readonly RawUsernoteType[] = [
{key: 'botban', color: 'black', text: 'Bot Ban'},
];

/**
* Default subreddit configuration to use if subreddit doesnt have one.
* Empty strings are used in the default config by the plugin even though
* this doesn't match the type exactly.
*/
export const DEFAULT_CONFIG = {
ver: LATEST_KNOWN_CONFIG_SCHEMA,
domainTags: '',
removalReasons: '',
modMacros: '',
usernoteColors: '',
banMacros: '',
};

/**
* Checks the schema version of raw subreddit config data and attempts to update
* it to the latest known schema version if it's out of date. Throws an error if
Expand Down

0 comments on commit ea0b3f8

Please sign in to comment.