Import Instagram archive to a Bluesky account
9
fork

Configure Feed

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

Moved tests to be side by side with their implementations.

+143 -32
+1 -1
jest.config.js
··· 1 1 module.exports = { 2 2 preset: 'ts-jest', 3 3 testEnvironment: 'node', 4 - roots: ['<rootDir>/src', '<rootDir>/tests'], 4 + roots: ['<rootDir>/src'], 5 5 testMatch: ['**/*.test.ts'], 6 6 transform: { 7 7 '^.+\\.tsx?$': 'ts-jest'
+139
src/video/video.test.ts
··· 1 + import { validateVideo, getVideoDimensions } from './video'; 2 + import path from 'path'; 3 + import { processVideoPost } from './video'; 4 + import { BlueskyClient } from '../bluesky/bluesky'; 5 + 6 + describe('Video Processing', () => { 7 + const testVideoPath = path.join(__dirname, '../transfer/test_videos/AQM8KYlOYHTF5GlP43eMroHUpmnFHJh5CnCJUdRUeqWxG4tNX7D43eM77F152vfi4znTzgkFTTzzM4nHa_v8ugmP4WPRJtjKPZX5pko_17845940218109367.mp4'); 8 + 9 + describe('validateVideo', () => { 10 + test('should reject videos larger than 100MB', () => { 11 + const largeBuffer = Buffer.alloc(101 * 1024 * 1024); // 101MB 12 + expect(validateVideo(largeBuffer)).toBe(false); 13 + }); 14 + 15 + test('should accept videos smaller than 100MB', () => { 16 + const smallBuffer = Buffer.alloc(50 * 1024 * 1024); // 50MB 17 + expect(validateVideo(smallBuffer)).toBe(true); 18 + }); 19 + }); 20 + 21 + describe('getVideoDimensions', () => { 22 + test('should get correct dimensions from test video', async () => { 23 + const dimensions = await getVideoDimensions(testVideoPath); 24 + expect(dimensions).toEqual({ 25 + width: 640, 26 + height: 640 27 + }); 28 + }); 29 + 30 + test('should throw error for non-existent file', async () => { 31 + await expect( 32 + getVideoDimensions('nonexistent/video.mp4') 33 + ).rejects.toThrow(); 34 + }); 35 + 36 + test('should throw error for invalid video file', async () => { 37 + const invalidFilePath = path.join(__dirname, 'video.test.ts'); // Using this test file as invalid video 38 + await expect( 39 + getVideoDimensions(invalidFilePath) 40 + ).rejects.toThrow(); 41 + }); 42 + }); 43 + 44 + describe('processVideoPost', () => { 45 + const mockVideoBuffer = Buffer.from('test video content'); 46 + 47 + // Mock BlueskyClient 48 + const mockBluesky = { 49 + uploadVideo: jest.fn().mockResolvedValue({ 50 + ref: { 51 + $link: 'test-cid' 52 + } 53 + }) 54 + } as unknown as BlueskyClient; 55 + 56 + beforeEach(() => { 57 + jest.clearAllMocks(); 58 + }); 59 + 60 + test('should process video successfully with upload', async () => { 61 + const result = await processVideoPost( 62 + testVideoPath, 63 + mockVideoBuffer, 64 + mockBluesky, 65 + false // not simulating 66 + ); 67 + 68 + expect(mockBluesky.uploadVideo).toHaveBeenCalledWith(mockVideoBuffer); 69 + expect(result).toMatchObject({ 70 + $type: 'app.bsky.embed.video', 71 + video: { 72 + $type: 'blob', 73 + ref: { 74 + $link: 'test-cid' 75 + } 76 + }, 77 + aspectRatio: { 78 + width: 640, 79 + height: 640 80 + } 81 + }); 82 + }); 83 + 84 + test('should process video in simulation mode without upload', async () => { 85 + const result = await processVideoPost( 86 + testVideoPath, 87 + mockVideoBuffer, 88 + mockBluesky, 89 + true // simulating 90 + ); 91 + 92 + expect(mockBluesky.uploadVideo).not.toHaveBeenCalled(); 93 + expect(result).toMatchObject({ 94 + $type: 'app.bsky.embed.video', 95 + video: { 96 + $type: 'blob', 97 + ref: { 98 + $link: '' 99 + } 100 + } 101 + }); 102 + }); 103 + 104 + test('should process video without Bluesky client', async () => { 105 + const result = await processVideoPost( 106 + testVideoPath, 107 + mockVideoBuffer, 108 + null, 109 + false 110 + ); 111 + 112 + expect(result).toMatchObject({ 113 + $type: 'app.bsky.embed.video', 114 + video: { 115 + $type: 'blob', 116 + ref: { 117 + $link: '' 118 + } 119 + } 120 + }); 121 + }); 122 + 123 + test('should throw error for undefined buffer', async () => { 124 + await expect( 125 + processVideoPost(testVideoPath, undefined as unknown as Buffer, mockBluesky, false) 126 + ).rejects.toThrow('Video buffer is undefined'); 127 + }); 128 + 129 + test('should throw error when upload fails', async () => { 130 + const failingBluesky = { 131 + uploadVideo: jest.fn().mockResolvedValue(null) 132 + } as unknown as BlueskyClient; 133 + 134 + await expect( 135 + processVideoPost(testVideoPath, mockVideoBuffer, failingBluesky, false) 136 + ).rejects.toThrow('Failed to get video upload reference'); 137 + }); 138 + }); 139 + });
tests/app.test.ts src/instagram-to-bluesky.test.ts
tests/bluesky.test.ts src/bluesky/bluesky.test.ts
+3 -3
tests/media.test.ts src/media/media.test.ts
··· 1 - import { getMimeType, processMedia, processPost } from "../src/media"; 1 + import { getMimeType, processMedia, processPost } from "./media"; 2 2 import path from "path"; 3 3 import fs from "fs"; 4 - import { BlueskyClient } from '../src/bluesky'; 5 - import { createVideoEmbed, processVideoPost } from '../src/video'; 4 + import { BlueskyClient } from '../bluesky/bluesky'; 5 + import { createVideoEmbed, processVideoPost } from '../video/video'; 6 6 7 7 // Mock the file system 8 8 jest.mock("fs", () => ({
-28
tests/video.test.ts
··· 1 - import { validateVideo, getVideoDimensions } from '../src/video'; 2 - import fs from 'fs'; 3 - import path from 'path'; 4 - 5 - describe('Video Processing', () => { 6 - describe('validateVideo', () => { 7 - test('should reject videos larger than 100MB', () => { 8 - const largeBuffer = Buffer.alloc(101 * 1024 * 1024); // 101MB 9 - expect(validateVideo(largeBuffer)).toBe(false); 10 - }); 11 - 12 - test('should accept videos smaller than 100MB', () => { 13 - const smallBuffer = Buffer.alloc(50 * 1024 * 1024); // 50MB 14 - expect(validateVideo(smallBuffer)).toBe(true); 15 - }); 16 - }); 17 - 18 - describe('getVideoDimensions', () => { 19 - test('should get correct dimensions from test video', async () => { 20 - const testVideoPath = path.join(__dirname, '../transfer/test_videos/AQM8KYlOYHTF5GlP43eMroHUpmnFHJh5CnCJUdRUeqWxG4tNX7D43eM77F152vfi4znTzgkFTTzzM4nHa_v8ugmP4WPRJtjKPZX5pko_17845940218109367.mp4'); 21 - const dimensions = await getVideoDimensions(testVideoPath); 22 - expect(dimensions).toEqual({ 23 - width: 640, 24 - height: 640 25 - }); 26 - }); 27 - }); 28 - });