diff --git a/src/comment.ts b/lib/comment.d.ts similarity index 57% rename from src/comment.ts rename to lib/comment.d.ts index 723e1ad..d5b262f 100644 --- a/src/comment.ts +++ b/lib/comment.d.ts @@ -54,54 +54,20 @@ export class Comment { * Creates a new comment. * @param options An object providing values to initialize this instance. */ - constructor(options: CommentOptions = {}) { - this.author = options.author ?? null; - this.content = options.content ?? ""; - this.context = options.context ?? []; - this.date = options.date ?? null; - this.permalink = options.permalink ? new URL(options.permalink) : null; - this.postModified = options.postModified ?? null; - this.recheckReason = options.recheckReason ?? ""; - this.referrer = options.referrer ? new URL(options.referrer) : null; - this.type = options.type ?? ""; - } + constructor(options?: CommentOptions); /** * Creates a new comment from the specified JSON object. * @param json A JSON object representing a comment. * @returns The instance corresponding to the specified JSON object. */ - static fromJson(json: Record): Comment { - const hasAuthor = Object.keys(json).filter(key => key.startsWith("comment_author") || key.startsWith("user")).length > 0; - return new this({ - author: hasAuthor ? Author.fromJson(json) : null, - content: typeof json.comment_content == "string" ? json.comment_content : "", - context: Array.isArray(json.comment_context) ? json.comment_context : [], - date: typeof json.comment_date_gmt == "string" ? new Date(json.comment_date_gmt) : null, - permalink: typeof json.permalink == "string" ? json.permalink : "", - postModified: typeof json.comment_post_modified_gmt == "string" ? new Date(json.comment_post_modified_gmt) : null, - recheckReason: typeof json.recheck_reason == "string" ? json.recheck_reason : "", - referrer: typeof json.referrer == "string" ? json.referrer : "", - type: typeof json.comment_type == "string" ? json.comment_type : "" - }); - } + static fromJson(json: Record): Comment; /** * Returns a JSON representation of this object. * @returns The JSON representation of this object. */ - toJSON(): Record { - const map = this.author ? this.author.toJSON() : {}; - if (this.content) map.comment_content = this.content; - if (this.context.length) map.comment_context = this.context; - if (this.date) map.comment_date_gmt = this.date.toJSON(); - if (this.permalink) map.permalink = this.permalink.href; - if (this.postModified) map.comment_post_modified_gmt = this.postModified.toJSON(); - if (this.recheckReason) map.recheck_reason = this.recheckReason; - if (this.referrer) map.referrer = this.referrer.href; - if (this.type) map.comment_type = this.type; - return map; - } + toJSON(): Record; } /** @@ -158,7 +124,7 @@ export type CommentOptions = Partial<{ /** * Specifies the type of a comment. */ -export const CommentType = Object.freeze({ +export const CommentType: Readonly<{ /** * A blog post. @@ -194,7 +160,7 @@ export const CommentType = Object.freeze({ * A new user account. */ signup: "signup" -}); +}>; /** * Specifies the type of a comment. diff --git a/src/comment.coffee b/src/comment.coffee new file mode 100644 index 0000000..e564489 --- /dev/null +++ b/src/comment.coffee @@ -0,0 +1,83 @@ +# Represents a comment submitted by an author. +export class Comment + + # Creates a new comment. + constructor: (options = {}) -> + + # The comment's author. + @author = options.author ? null + + # The comment's content. + @content = options.content ? "" + + # The context in which this comment was posted. + @context = options.context ? [] + + # The UTC timestamp of the creation of the comment. + @date = options.date ? null + + # The permanent location of the entry the comment is submitted to. + @permalink = if options.permalink then new URL options.permalink else null + + # The UTC timestamp of the publication time for the post, page or thread on which the comment was posted. + @postModified = options.postModified ? null + + # A string describing why the content is being rechecked. + @recheckReason = options.recheckReason ? "" + + # The URL of the webpage that linked to the entry being requested. + @referrer = if options.referrer then new URL options.referrer else null + + # The comment's type. + @type = options.type ? "" + + # Creates a new comment from the specified JSON object. + @fromJson: (json) -> + hasAuthor = Object.keys(json).filter((key) -> key.startsWith "comment_author" or key.startsWith "user").length > 0 + new @ + author: if hasAuthor then Author.fromJson json else null + content: if typeof json.comment_content == "string" then json.comment_content else "" + context: if Array.isArray json.comment_context then json.comment_context else [] + date: if typeof json.comment_date_gmt == "string" then new Date json.comment_date_gmt else null + permalink: if typeof json.permalink == "string" then json.permalink else "" + postModified: if typeof json.comment_post_modified_gmt == "string" then new Date json.comment_post_modified_gmt else null + recheckReason: if typeof json.recheck_reason == "string" then json.recheck_reason else "" + referrer: if typeof json.referrer == "string" then json.referrer else "" + type: if typeof json.comment_type == "string" then json.comment_type else "" + + # Returns a JSON representation of this object. + toJSON: -> + map = @author?.toJSON() ? {} + map.comment_content = @content if @content + map.comment_context = @context if @context.length + map.comment_date_gmt = @date.toJSON() if @date + map.permalink = @permalink.href if @permalink + map.comment_post_modified_gmt = @postModified.toJSON() if @postModified + map.recheck_reason = @recheckReason if @recheckReason + map.referrer = @referrer.href if @referrer + map.comment_type = @type if @type + map + +# Specifies the type of a comment. +export CommentType = Object.freeze + + # A blog post. + blogPost: "blog-post" + + # A blog comment. + comment: "comment" + + # A contact form or feedback form submission. + contactForm: "contact-form" + + # A top-level forum post. + forumPost: "forum-post" + + # A message sent between just a few users. + message: "message" + + # A reply to a top-level forum post. + reply: "reply" + + # A new user account. + signup: "signup" diff --git a/test/comment_test.coffee b/test/comment_test.coffee new file mode 100644 index 0000000..fb84bac --- /dev/null +++ b/test/comment_test.coffee @@ -0,0 +1,62 @@ +import {Author, Comment, CommentType} from "@cedx/akismet" +import {equal, ok} from "node:assert/strict" +import {describe, it} from "node:test" + +# Tests the features of the `Comment` class. +describe "Comment", -> + describe "fromJson()", -> + it "should return an empty instance with an empty map", -> + comment = Comment.fromJson {} + equal comment.author, null + equal comment.content.length, 0 + equal comment.date, null + equal comment.permalink, null + equal comment.postModified, null + equal comment.recheckReason.length, 0 + equal comment.referrer, null + equal comment.type.length, 0 + + it "should return an initialized instance with a non-empty map", -> + comment = Comment.fromJson + comment_author: "Cédric Belin" + comment_content: "A user comment." + comment_date_gmt: "2000-01-01T00:00:00.000Z" + comment_type: "blog-post" + referrer: "https://belin.io" + recheck_reason: "The comment has been changed." + user_ip: "127.0.0.1" + + ok comment.author instanceof Author + equal comment.author.ipAddress, "127.0.0.1" + equal comment.author.name, "Cédric Belin" + equal comment.content, "A user comment." + ok comment.date instanceof Date + equal comment.date.toISOString(), "2000-01-01T00:00:00.000Z" + ok comment.referrer instanceof URL + equal comment.recheckReason, "The comment has been changed." + equal comment.referrer.href, "https://belin.io/" + equal comment.type, CommentType.blogPost + + describe "toJSON()", -> + it "should return only the author info with a newly created instance", -> + json = new Comment(author: new Author(ipAddress: "127.0.0.1")).toJSON() + equal Object.keys(json).length, 1 + equal json.user_ip, "127.0.0.1" + + it "should return a non-empty map with an initialized instance", -> + json = new Comment( + author: new Author ipAddress: "127.0.0.1", name: "Cédric Belin", userAgent: "Doom/6.6.6" + content: "A user comment." + date: new Date "2000-01-01T00:00:00.000Z" + referrer: "https://belin.io" + type: CommentType.blogPost + ).toJSON() + + equal Object.keys(json).length, 7 + equal json.comment_author, "Cédric Belin" + equal json.comment_content, "A user comment." + equal json.comment_date_gmt, "2000-01-01T00:00:00.000Z" + equal json.comment_type, "blog-post" + equal json.referrer, "https://belin.io/" + equal json.user_agent, "Doom/6.6.6" + equal json.user_ip, "127.0.0.1" diff --git a/test/comment_test.js b/test/comment_test.js deleted file mode 100644 index 6c84f91..0000000 --- a/test/comment_test.js +++ /dev/null @@ -1,72 +0,0 @@ -import {Author, Comment, CommentType} from "@cedx/akismet"; -import {equal, ok} from "node:assert/strict"; -import {describe, it} from "node:test"; - -/** - * Tests the features of the {@link Comment} class. - */ -describe("Comment", () => { - describe("fromJson()", () => { - it("should return an empty instance with an empty map", () => { - const comment = Comment.fromJson({}); - equal(comment.author, null); - equal(comment.content.length, 0); - equal(comment.date, null); - equal(comment.permalink, null); - equal(comment.postModified, null); - equal(comment.recheckReason.length, 0); - equal(comment.referrer, null); - equal(comment.type.length, 0); - }); - - it("should return an initialized instance with a non-empty map", () => { - const comment = Comment.fromJson({ - comment_author: "Cédric Belin", - comment_content: "A user comment.", - comment_date_gmt: "2000-01-01T00:00:00.000Z", - comment_type: "blog-post", - referrer: "https://belin.io", - recheck_reason: "The comment has been changed.", - user_ip: "127.0.0.1" - }); - - ok(comment.author instanceof Author); - equal(comment.author.ipAddress, "127.0.0.1"); - equal(comment.author.name, "Cédric Belin"); - equal(comment.content, "A user comment."); - ok(comment.date instanceof Date); - equal(comment.date.toISOString(), "2000-01-01T00:00:00.000Z"); - ok(comment.referrer instanceof URL); - equal(comment.recheckReason, "The comment has been changed."); - equal(comment.referrer.href, "https://belin.io/"); - equal(comment.type, CommentType.blogPost); - }); - }); - - describe("toJSON()", () => { - it("should return only the author info with a newly created instance", () => { - const json = new Comment({author: new Author({ipAddress: "127.0.0.1"})}).toJSON(); - equal(Object.keys(json).length, 1); - equal(json.user_ip, "127.0.0.1"); - }); - - it("should return a non-empty map with an initialized instance", () => { - const json = new Comment({ - author: new Author({ipAddress: "127.0.0.1", name: "Cédric Belin", userAgent: "Doom/6.6.6"}), - content: "A user comment.", - date: new Date("2000-01-01T00:00:00.000Z"), - referrer: "https://belin.io", - type: CommentType.blogPost - }).toJSON(); - - equal(Object.keys(json).length, 7); - equal(json.comment_author, "Cédric Belin"); - equal(json.comment_content, "A user comment."); - equal(json.comment_date_gmt, "2000-01-01T00:00:00.000Z"); - equal(json.comment_type, "blog-post"); - equal(json.referrer, "https://belin.io/"); - equal(json.user_agent, "Doom/6.6.6"); - equal(json.user_ip, "127.0.0.1"); - }); - }); -});