Import Instagram archive to a Bluesky account
9
fork

Configure Feed

Select the types of activity you want to include in your feed.

Added min-max date unit tests

+147 -1
+147
src/instagram-to-bluesky.test.ts
··· 188 188 expect(logger.warn).toHaveBeenCalledWith('Skipping post - After MAX_DATE [Wed, 01 Jan 2025 00:00:00 GMT]'); 189 189 }); 190 190 191 + // New tests for MIN_DATE and MAX_DATE functionality 192 + describe('Date Filtering', () => { 193 + test('should include posts exactly on MIN_DATE', async () => { 194 + process.env.MIN_DATE = '2024-01-01'; 195 + 196 + const exactMinDatePost = { 197 + creation_timestamp: new Date('2024-01-01').getTime() / 1000, 198 + title: 'Exact Min Date Post', 199 + media: [{ 200 + creation_timestamp: new Date('2024-01-01').getTime() / 1000, 201 + title: 'Exact Min Date Media' 202 + }] 203 + }; 204 + 205 + (fs.readFileSync as jest.Mock).mockReturnValue(JSON.stringify([exactMinDatePost])); 206 + 207 + await main(); 208 + 209 + // The post should be processed, not skipped 210 + expect(logger.warn).not.toHaveBeenCalledWith( 211 + expect.stringContaining('Skipping post - Before MIN_DATE') 212 + ); 213 + expect(InstagramMediaProcessor).toHaveBeenCalledWith( 214 + expect.arrayContaining([expect.objectContaining({ title: 'Exact Min Date Post' })]), 215 + expect.any(String) 216 + ); 217 + }); 218 + 219 + test('should exclude posts exactly on MAX_DATE', async () => { 220 + process.env.MAX_DATE = '2024-01-01'; 221 + 222 + const exactMaxDatePost = { 223 + creation_timestamp: new Date('2024-01-01').getTime() / 1000, 224 + title: 'Exact Max Date Post', 225 + media: [{ 226 + creation_timestamp: new Date('2024-01-01').getTime() / 1000, 227 + title: 'Exact Max Date Media' 228 + }] 229 + }; 230 + 231 + (fs.readFileSync as jest.Mock).mockReturnValue(JSON.stringify([exactMaxDatePost])); 232 + 233 + await main(); 234 + 235 + // The post should be processed, not skipped (MAX_DATE is exclusive) 236 + expect(logger.warn).not.toHaveBeenCalledWith( 237 + expect.stringContaining('Skipping post - After MAX_DATE') 238 + ); 239 + expect(InstagramMediaProcessor).toHaveBeenCalledWith( 240 + expect.arrayContaining([expect.objectContaining({ title: 'Exact Max Date Post' })]), 241 + expect.any(String) 242 + ); 243 + }); 244 + 245 + test('should filter posts with both MIN_DATE and MAX_DATE set', async () => { 246 + process.env.MIN_DATE = '2023-01-01'; 247 + process.env.MAX_DATE = '2025-01-01'; 248 + 249 + const posts = [ 250 + { 251 + creation_timestamp: new Date('2022-01-01').getTime() / 1000, // Too old 252 + title: 'Too Old Post', 253 + media: [{ creation_timestamp: new Date('2022-01-01').getTime() / 1000, title: 'Old Media' }] 254 + }, 255 + { 256 + creation_timestamp: new Date('2023-06-01').getTime() / 1000, // In range 257 + title: 'In Range Post 1', 258 + media: [{ creation_timestamp: new Date('2023-06-01').getTime() / 1000, title: 'In Range Media 1' }] 259 + }, 260 + { 261 + creation_timestamp: new Date('2024-06-01').getTime() / 1000, // In range 262 + title: 'In Range Post 2', 263 + media: [{ creation_timestamp: new Date('2024-06-01').getTime() / 1000, title: 'In Range Media 2' }] 264 + }, 265 + { 266 + creation_timestamp: new Date('2026-01-01').getTime() / 1000, // Too new 267 + title: 'Too New Post', 268 + media: [{ creation_timestamp: new Date('2026-01-01').getTime() / 1000, title: 'New Media' }] 269 + } 270 + ]; 271 + 272 + (fs.readFileSync as jest.Mock).mockReturnValue(JSON.stringify(posts)); 273 + 274 + await main(); 275 + 276 + // Should skip the too old post 277 + expect(logger.warn).toHaveBeenCalledWith( 278 + 'Skipping post - Before MIN_DATE: [Sat, 01 Jan 2022 00:00:00 GMT]' 279 + ); 280 + 281 + // Should skip the too new post 282 + expect(logger.warn).toHaveBeenCalledWith( 283 + 'Skipping post - After MAX_DATE [Thu, 01 Jan 2026 00:00:00 GMT]' 284 + ); 285 + 286 + // Should process the in-range posts 287 + expect(InstagramMediaProcessor).toHaveBeenCalledWith( 288 + expect.arrayContaining([ 289 + expect.objectContaining({ title: 'In Range Post 1' }), 290 + expect.objectContaining({ title: 'In Range Post 2' }) 291 + ]), 292 + expect.any(String) 293 + ); 294 + }); 295 + 296 + test('should use media timestamp when post timestamp is missing', async () => { 297 + process.env.MIN_DATE = '2023-01-01'; 298 + process.env.MAX_DATE = '2025-01-01'; 299 + 300 + const posts = [ 301 + { 302 + // No creation_timestamp at post level 303 + title: 'Post with only media timestamp', 304 + media: [{ 305 + creation_timestamp: new Date('2024-01-01').getTime() / 1000, 306 + title: 'Media with timestamp' 307 + }] 308 + }, 309 + { 310 + // No creation_timestamp at post level 311 + title: 'Post with old media timestamp', 312 + media: [{ 313 + creation_timestamp: new Date('2022-01-01').getTime() / 1000, 314 + title: 'Too old media' 315 + }] 316 + } 317 + ]; 318 + 319 + (fs.readFileSync as jest.Mock).mockReturnValue(JSON.stringify(posts)); 320 + 321 + await main(); 322 + 323 + // Should skip the post with old media timestamp 324 + expect(logger.warn).toHaveBeenCalledWith( 325 + 'Skipping post - Before MIN_DATE: [Sat, 01 Jan 2022 00:00:00 GMT]' 326 + ); 327 + 328 + // Should process the post with valid media timestamp 329 + expect(InstagramMediaProcessor).toHaveBeenCalledWith( 330 + expect.arrayContaining([ 331 + expect.objectContaining({ title: 'Post with only media timestamp' }) 332 + ]), 333 + expect.any(String) 334 + ); 335 + }); 336 + }); 337 + 191 338 test('should handle posts with missing dates', async () => { 192 339 const invalidPost = { 193 340 title: 'Invalid Post',
-1
src/instagram-to-bluesky.ts
··· 201 201 continue; 202 202 } 203 203 204 - // TODO add unit test for min max posts. 205 204 // If MIN_DATE configured validate the creation date is after the minimum date config. 206 205 if (MIN_DATE && checkDate && checkDate < MIN_DATE) { 207 206 logger.warn(