/** * @copyright NHCarrigan * @license Naomi's Public License * @author Naomi Carrigan */ import { GameStatus, BookStatus, MangaStatus, MusicStatus, MusicType, ShowStatus, ShowType } from "../src"; import { SuggestionEntity, SuggestionStatus } from "../src/lib/suggestion.types"; import type { Suggestion, SuggestionUser, CreateSuggestionDto, DeclineSuggestionDto, CreateGameSuggestionDto, CreateBookSuggestionDto, CreateMusicSuggestionDto, CreateArtSuggestionDto, CreateShowSuggestionDto, CreateMangaSuggestionDto, AcceptWithEditsDto, } from "../src/lib/suggestion.types"; describe("suggestion Types", () => { describe("suggestionEntity enum", () => { it("should have the correct values", () => { expect(SuggestionEntity.game).toBe("GAME"); expect(SuggestionEntity.book).toBe("BOOK"); expect(SuggestionEntity.music).toBe("MUSIC"); expect(SuggestionEntity.art).toBe("ART"); expect(SuggestionEntity.show).toBe("SHOW"); expect(SuggestionEntity.manga).toBe("MANGA"); }); it("should have all expected enum values", () => { const values = Object.values(SuggestionEntity); expect(values).toHaveLength(6); expect(values).toContain("GAME"); expect(values).toContain("BOOK"); expect(values).toContain("MUSIC"); expect(values).toContain("ART"); expect(values).toContain("SHOW"); expect(values).toContain("MANGA"); }); }); describe("suggestionStatus enum", () => { it("should have the correct values", () => { expect(SuggestionStatus.unreviewed).toBe("UNREVIEWED"); expect(SuggestionStatus.accepted).toBe("ACCEPTED"); expect(SuggestionStatus.declined).toBe("DECLINED"); }); it("should have all expected enum values", () => { const values = Object.values(SuggestionStatus); expect(values).toHaveLength(3); expect(values).toContain("UNREVIEWED"); expect(values).toContain("ACCEPTED"); expect(values).toContain("DECLINED"); }); }); describe("suggestionUser interface", () => { it("should accept valid user object", () => { const user: SuggestionUser = { avatar: "https://example.com/avatar.png", id: "user123", inDiscord: true, isMod: false, isStaff: false, isVip: false, username: "suggester", }; expect(user.inDiscord).toBeTruthy(); expect(user.isVip).toBeFalsy(); }); it("should accept user without avatar", () => { const user: SuggestionUser = { id: "user456", inDiscord: true, isMod: false, isStaff: true, isVip: true, username: "vipuser", }; expect(user.avatar).toBeUndefined(); expect(user.isVip).toBeTruthy(); expect(user.isStaff).toBeTruthy(); }); }); describe("suggestion interface", () => { it("should accept game suggestion", () => { const gameSuggestion: Suggestion = { createdAt: new Date("2024-01-15"), entityType: SuggestionEntity.game, gameData: { coverImage: "https://example.com/hades.jpg", notes: "Amazing roguelike", platform: "Nintendo Switch", status: GameStatus.backlog, title: "Hades", }, id: "sug123", status: SuggestionStatus.unreviewed, title: "Hades", updatedAt: new Date("2024-01-15"), user: { id: "user123", inDiscord: true, isMod: false, isStaff: false, isVip: false, username: "gamer", }, userId: "user123", }; expect(gameSuggestion.entityType).toBe(SuggestionEntity.game); expect(gameSuggestion.gameData).toBeDefined(); expect(gameSuggestion.bookData).toBeUndefined(); }); it("should accept book suggestion", () => { const bookSuggestion: Suggestion = { bookData: { author: "George Orwell", isbn: "978-0-452-28423-4", notes: "Dystopian classic", status: BookStatus.toRead, title: "1984", }, createdAt: new Date("2024-01-20"), entityType: SuggestionEntity.book, id: "sug456", status: SuggestionStatus.accepted, title: "1984", updatedAt: new Date("2024-01-21"), user: { id: "user456", inDiscord: false, isMod: false, isStaff: false, isVip: true, username: "reader", }, userId: "user456", }; expect(bookSuggestion.entityType).toBe(SuggestionEntity.book); expect(bookSuggestion.bookData).toBeDefined(); expect(bookSuggestion.gameData).toBeUndefined(); }); it("should accept declined suggestion with reason", () => { const declinedSuggestion: Suggestion = { createdAt: new Date("2024-02-01"), declineReason: "Already in the library", entityType: SuggestionEntity.music, id: "sug789", musicData: { artist: "Pink Floyd", status: MusicStatus.wantToListen, title: "Dark Side of the Moon", type: MusicType.album, }, status: SuggestionStatus.declined, title: "Dark Side of the Moon", updatedAt: new Date("2024-02-02"), user: { id: "user789", inDiscord: true, isMod: false, isStaff: false, isVip: false, username: "suggester", }, userId: "user789", }; expect(declinedSuggestion.status).toBe(SuggestionStatus.declined); expect(declinedSuggestion.declineReason).toBe("Already in the library"); }); it("should accept art suggestion", () => { const artSuggestion: Suggestion = { artData: { artist: "Jane Doe", description: "A stunning sunset painting", imageUrl: "https://example.com/sunset.jpg", title: "Beautiful Sunset", }, createdAt: new Date("2024-02-10"), entityType: SuggestionEntity.art, id: "sug999", status: SuggestionStatus.unreviewed, title: "Beautiful Sunset", updatedAt: new Date("2024-02-10"), user: { id: "user999", inDiscord: true, isMod: true, isStaff: false, isVip: false, username: "artlover", }, userId: "user999", }; expect(artSuggestion.entityType).toBe(SuggestionEntity.art); expect(artSuggestion.artData).toBeDefined(); }); it("should accept show and manga suggestions", () => { const showSuggestion: Suggestion = { createdAt: new Date("2024-02-15"), entityType: SuggestionEntity.show, id: "sug111", showData: { status: ShowStatus.wantToWatch, title: "Breaking Bad", type: ShowType.tvSeries, }, status: SuggestionStatus.unreviewed, title: "Breaking Bad", updatedAt: new Date("2024-02-15"), user: { id: "user111", inDiscord: false, isMod: false, isStaff: true, isVip: false, username: "tvfan", }, userId: "user111", }; const mangaSuggestion: Suggestion = { createdAt: new Date("2024-02-20"), entityType: SuggestionEntity.manga, id: "sug222", mangaData: { author: "Eiichiro Oda", status: MangaStatus.reading, title: "One Piece", }, status: SuggestionStatus.accepted, title: "One Piece", updatedAt: new Date("2024-02-21"), user: { id: "user222", inDiscord: true, isMod: true, isStaff: true, isVip: true, username: "mangareader", }, userId: "user222", }; expect(showSuggestion.entityType).toBe(SuggestionEntity.show); expect(mangaSuggestion.entityType).toBe(SuggestionEntity.manga); }); }); describe("createSuggestionDto types", () => { it("should accept game suggestion DTO", () => { const gameDto: CreateGameSuggestionDto = { coverImage: "https://example.com/hollow.jpg", entityType: SuggestionEntity.game, notes: "Great metroidvania", platform: "PC", title: "Hollow Knight", }; expect(gameDto.entityType).toBe(SuggestionEntity.game); expect(gameDto.platform).toBe("PC"); }); it("should accept book suggestion DTO", () => { const bookDto: CreateBookSuggestionDto = { author: "J.R.R. Tolkien", coverImage: "https://example.com/hobbit.jpg", entityType: SuggestionEntity.book, isbn: "978-0-547-92822-7", notes: "Fantasy classic", title: "The Hobbit", }; expect(bookDto.entityType).toBe(SuggestionEntity.book); expect(bookDto.author).toBe("J.R.R. Tolkien"); }); it("should accept music suggestion DTO", () => { const musicDto: CreateMusicSuggestionDto = { artist: "Pink Floyd", coverArt: "https://example.com/wall.jpg", entityType: SuggestionEntity.music, notes: "Rock opera", title: "The Wall", type: "ALBUM", }; expect(musicDto.entityType).toBe(SuggestionEntity.music); expect(musicDto.type).toBe("ALBUM"); }); it("should accept art suggestion DTO", () => { const artDto: CreateArtSuggestionDto = { artist: "Vincent van Gogh", description: "Famous painting", entityType: SuggestionEntity.art, imageUrl: "https://example.com/starry.jpg", title: "Starry Night", }; expect(artDto.entityType).toBe(SuggestionEntity.art); expect(artDto.imageUrl).toBe("https://example.com/starry.jpg"); }); it("should accept show suggestion DTO", () => { const showDto: CreateShowSuggestionDto = { coverImage: "https://example.com/office.jpg", entityType: SuggestionEntity.show, notes: "Comedy series", title: "The Office", type: "TV_SERIES", }; expect(showDto.entityType).toBe(SuggestionEntity.show); expect(showDto.type).toBe("TV_SERIES"); }); it("should accept manga suggestion DTO", () => { const mangaDto: CreateMangaSuggestionDto = { author: "Tsugumi Ohba", coverImage: "https://example.com/deathnote.jpg", entityType: SuggestionEntity.manga, notes: "Psychological thriller", title: "Death Note", }; expect(mangaDto.entityType).toBe(SuggestionEntity.manga); expect(mangaDto.author).toBe("Tsugumi Ohba"); }); it("should work with union type", () => { const suggestions: Array = [ { entityType: SuggestionEntity.game, title: "Game Title", }, { author: "Author Name", entityType: SuggestionEntity.book, title: "Book Title", }, ]; expect(suggestions).toHaveLength(2); expect(suggestions[0].entityType).toBe(SuggestionEntity.game); expect(suggestions[1].entityType).toBe(SuggestionEntity.book); }); }); describe("declineSuggestionDto interface", () => { it("should accept empty decline DTO", () => { const declineDto: DeclineSuggestionDto = {}; expect(declineDto.reason).toBeUndefined(); }); it("should accept decline DTO with reason", () => { const declineDto: DeclineSuggestionDto = { reason: "Already exists in the library", }; expect(declineDto.reason).toBe("Already exists in the library"); }); }); describe("acceptWithEditsDto interface", () => { it("should accept empty edits DTO", () => { const editsDto: AcceptWithEditsDto = {}; expect(editsDto).toEqual({}); }); it("should accept edits for book fields", () => { const editsDto: AcceptWithEditsDto = { author: "Corrected Author", coverImage: "https://example.com/new-cover.jpg", isbn: "978-0-123-45678-9", links: [ { label: "Goodreads", url: "https://goodreads.com" } ], notes: "Updated notes", tags: [ "fiction", "classic" ], title: "Corrected Title", }; expect(editsDto.title).toBe("Corrected Title"); expect(editsDto.author).toBe("Corrected Author"); expect(editsDto.tags).toHaveLength(2); }); it("should accept edits for music fields", () => { const editsDto: AcceptWithEditsDto = { artist: "Artist Name", coverArt: "https://example.com/album.jpg", title: "Album Title", type: "ALBUM", }; expect(editsDto.artist).toBe("Artist Name"); expect(editsDto.type).toBe("ALBUM"); expect(editsDto.coverArt).toBe("https://example.com/album.jpg"); }); it("should accept edits for game fields", () => { const editsDto: AcceptWithEditsDto = { coverImage: "https://example.com/game.jpg", notes: "Action RPG", platform: "PlayStation 5", title: "Game Title", }; expect(editsDto.platform).toBe("PlayStation 5"); }); it("should accept edits for art fields", () => { const editsDto: AcceptWithEditsDto = { artist: "Artist Name", description: "Beautiful artwork", imageUrl: "https://example.com/art.jpg", title: "Art Title", }; expect(editsDto.description).toBe("Beautiful artwork"); expect(editsDto.imageUrl).toBe("https://example.com/art.jpg"); }); }); });