1+ import { NewsArticleModel } from "./NewsArticle"
2+
3+ describe ( "NewsArticle" , ( ) => {
4+ const createTestArticle = ( overrides = { } ) => {
5+ return NewsArticleModel . create ( {
6+ article_id : "test-1" ,
7+ title : "Test Health Article" ,
8+ link : "https://example.com/article" ,
9+ pubDate : "2024-01-15T10:30:00Z" ,
10+ source_id : "test-source" ,
11+ source_name : "Healthcare Today" ,
12+ source_url : "https://healthcaretoday.com" ,
13+ keywords : [ "health" , "medicine" ] ,
14+ creator : [ "Dr. Jane Smith" ] ,
15+ description : "This is a test article about healthcare developments and medical research findings." ,
16+ content : "Full article content with detailed information about healthcare trends and medical breakthroughs." ,
17+ country : [ "US" , "GH" ] ,
18+ category : [ "health" , "medicine" ] ,
19+ source_priority : 1500 ,
20+ sentiment : "positive" ,
21+ image_url : "https://example.com/image.jpg" ,
22+ ...overrides ,
23+ } )
24+ }
25+
26+ test ( "can be created with minimal props" , ( ) => {
27+ const instance = NewsArticleModel . create ( {
28+ article_id : "1" ,
29+ title : "Test Article" ,
30+ link : "https://example.com/test" ,
31+ pubDate : new Date ( ) . toISOString ( ) ,
32+ source_id : "source1" ,
33+ source_name : "Test Source" ,
34+ source_url : "https://example.com/source" ,
35+ } )
36+
37+ expect ( instance ) . toBeTruthy ( )
38+ expect ( instance . keywords ) . toEqual ( [ ] )
39+ expect ( instance . description ) . toBe ( "" )
40+ expect ( instance . language ) . toBe ( "en" )
41+ } )
42+
43+ describe ( "date views" , ( ) => {
44+ test ( "formats dates correctly" , ( ) => {
45+ const article = createTestArticle ( { pubDate : "2024-01-15T10:30:00Z" } )
46+
47+ expect ( article . formattedDate ) . toMatch ( / 2 0 2 4 / )
48+ expect ( article . formattedDateTime ) . toContain ( "2024" )
49+ } )
50+
51+ test ( "handles invalid dates" , ( ) => {
52+ const article = createTestArticle ( { pubDate : "invalid-date" } )
53+ expect ( article . formattedDate ) . toBe ( "invalid-date" )
54+ expect ( article . timeAgo ) . toBe ( "" )
55+ } )
56+
57+ test ( "calculates time ago" , ( ) => {
58+ const oneHourAgo = new Date ( Date . now ( ) - 60 * 60 * 1000 )
59+ const article = createTestArticle ( { pubDate : oneHourAgo . toISOString ( ) } )
60+ expect ( article . timeAgo ) . toBe ( "1h ago" )
61+ } )
62+ } )
63+
64+ describe ( "multimedia views" , ( ) => {
65+ test ( "detects multimedia presence" , ( ) => {
66+ const withImage = createTestArticle ( { image_url : "test.jpg" , video_url : null } )
67+ const withVideo = createTestArticle ( { image_url : null , video_url : "test.mp4" } )
68+ const withNeither = createTestArticle ( { image_url : null , video_url : null } )
69+
70+ expect ( withImage . hasImage ) . toBe ( true )
71+ expect ( withImage . hasMultimedia ) . toBe ( true )
72+ expect ( withVideo . hasVideo ) . toBe ( true )
73+ expect ( withNeither . hasMultimedia ) . toBe ( false )
74+ } )
75+ } )
76+
77+ describe ( "content views" , ( ) => {
78+ test ( "handles categories and countries" , ( ) => {
79+ const article = createTestArticle ( { category : [ "health" , "medicine" ] , country : [ "US" , "CA" ] } )
80+ const empty = createTestArticle ( { category : [ ] , country : [ ] } )
81+
82+ expect ( article . primaryCategory ) . toBe ( "health" )
83+ expect ( article . allCategories ) . toBe ( "health, medicine" )
84+ expect ( article . primaryCountry ) . toBe ( "US" )
85+ expect ( empty . primaryCategory ) . toBe ( "General" )
86+ expect ( empty . allCountries ) . toBe ( "Global" )
87+ } )
88+
89+ test ( "handles authors" , ( ) => {
90+ const withAuthors = createTestArticle ( { creator : [ "John Doe" , "Jane Smith" ] } )
91+ const withoutAuthors = createTestArticle ( { creator : [ ] } )
92+
93+ expect ( withAuthors . authorName ) . toBe ( "John Doe, Jane Smith" )
94+ expect ( withAuthors . firstAuthor ) . toBe ( "John Doe" )
95+ expect ( withoutAuthors . authorName ) . toBe ( "Unknown" )
96+ } )
97+
98+ test ( "truncates descriptions" , ( ) => {
99+ const longDesc = "A" . repeat ( 150 )
100+ const article = createTestArticle ( { description : longDesc } )
101+
102+ expect ( article . shortDescription ) . toBe ( "A" . repeat ( 100 ) + "..." )
103+ expect ( article . mediumDescription ) . toBe ( "A" . repeat ( 150 ) )
104+ } )
105+ } )
106+
107+ describe ( "health detection" , ( ) => {
108+ test ( "detects health-related content" , ( ) => {
109+ const healthArticle = createTestArticle ( {
110+ title : "Medical Breakthrough" ,
111+ description : "" ,
112+ keywords : [ ]
113+ } )
114+ const nonHealthArticle = createTestArticle ( {
115+ title : "Tech Update" ,
116+ description : "Software news" ,
117+ keywords : [ "tech" ]
118+ } )
119+
120+ expect ( healthArticle . isHealthRelated ) . toBe ( true )
121+ expect ( nonHealthArticle . isHealthRelated ) . toBe ( false )
122+ } )
123+ } )
124+
125+ describe ( "priority and sentiment" , ( ) => {
126+ test ( "categorizes source priority" , ( ) => {
127+ const highPriority = createTestArticle ( { source_priority : 500 } )
128+ const lowPriority = createTestArticle ( { source_priority : 8000 } )
129+
130+ expect ( highPriority . sourcePriorityLabel ) . toBe ( "High Priority" )
131+ expect ( highPriority . sourcePriorityBadgeColor ) . toBe ( "green" )
132+ expect ( lowPriority . sourcePriorityLabel ) . toBe ( "Low Priority" )
133+ expect ( lowPriority . sourcePriorityBadgeColor ) . toBe ( "gray" )
134+ } )
135+
136+ test ( "handles sentiment" , ( ) => {
137+ const positive = createTestArticle ( { sentiment : "positive" } )
138+ const unknown = createTestArticle ( { sentiment : "" } )
139+
140+ expect ( positive . sentimentLabel ) . toBe ( "Positive" )
141+ expect ( positive . sentimentColor ) . toBe ( "green" )
142+ expect ( unknown . sentimentLabel ) . toBe ( "Unknown" )
143+ expect ( unknown . sentimentColor ) . toBe ( "gray" )
144+ } )
145+ } )
146+
147+ describe ( "Ghana detection" , ( ) => {
148+ test ( "identifies Ghana news" , ( ) => {
149+ const ghanaCode = createTestArticle ( { country : [ "GH" ] } )
150+ const ghanaName = createTestArticle ( { country : [ "Ghana" ] } )
151+ const nonGhana = createTestArticle ( { country : [ "US" ] } )
152+
153+ expect ( ghanaCode . isGhanaNews ) . toBe ( true )
154+ expect ( ghanaName . isGhanaNews ) . toBe ( true )
155+ expect ( nonGhana . isGhanaNews ) . toBe ( false )
156+ } )
157+ } )
158+
159+ describe ( "utility views" , ( ) => {
160+ test ( "provides utility properties" , ( ) => {
161+ const article = createTestArticle ( {
162+ content : "Test content" ,
163+ title : "Test Title" ,
164+ keywords : [ "health" , "test" ]
165+ } )
166+ const emptyTitle = createTestArticle ( { title : "" } )
167+
168+ expect ( article . hasContent ) . toBe ( true )
169+ expect ( article . displayTitle ) . toBe ( "Test Title" )
170+ expect ( article . shareUrl ) . toBe ( "https://example.com/article" )
171+ expect ( article . keywordsList ) . toBe ( "health, test" )
172+ expect ( article . readingTimeEstimate ) . toMatch ( / m i n r e a d / )
173+ expect ( emptyTitle . displayTitle ) . toBe ( "Untitled Article" )
174+ } )
175+ } )
176+
177+ describe ( "actions" , ( ) => {
178+ test ( "updates from API data" , ( ) => {
179+ const article = createTestArticle ( { title : "Original" } )
180+
181+ article . updateFromApi ( { title : "Updated" , sentiment : "negative" } )
182+
183+ expect ( article . title ) . toBe ( "Updated" )
184+ expect ( article . sentiment ) . toBe ( "negative" )
185+ } )
186+
187+ test ( "updates sentiment and AI summary" , ( ) => {
188+ const article = createTestArticle ( )
189+
190+ article . updateSentiment ( "neutral" )
191+ article . updateAiSummary ( "AI summary" )
192+
193+ expect ( article . sentiment ) . toBe ( "neutral" )
194+ expect ( article . ai_summary ) . toBe ( "AI summary" )
195+ } )
196+
197+ test ( "markAsRead executes without error" , ( ) => {
198+ const article = createTestArticle ( )
199+ expect ( ( ) => article . markAsRead ( ) ) . not . toThrow ( )
200+ } )
201+ } )
202+ } )
0 commit comments