# FitPub Federation Testing Guide This guide explains how to test the instance-to-instance federation functionality by running two FitPub instances locally. ## Prerequisites - Java 17+ - Maven 3.8+ - PostgreSQL 13+ with PostGIS extension - Two separate PostgreSQL databases - Two different port numbers for the applications ## Setup ### Step 1: Create Two PostgreSQL Databases ```bash # Connect to PostgreSQL psql -U postgres # Create databases CREATE DATABASE fitpub_instance1; CREATE DATABASE fitpub_instance2; # Enable PostGIS extension for both databases \c fitpub_instance1 CREATE EXTENSION IF NOT EXISTS postgis; \c fitpub_instance2 CREATE EXTENSION IF NOT EXISTS postgis; \q ``` ### Step 2: Prepare Application Profiles Create two separate application configuration files: #### `application-instance1.yml` ```yaml server: port: 8080 spring: datasource: url: jdbc:postgresql://localhost:5432/fitpub_instance1 username: postgres password: your_password jpa: hibernate: ddl-auto: validate fitpub: base-url: http://localhost:8080 domain: localhost:8080 logging: level: org.operaton.fitpub: DEBUG ``` #### `application-instance2.yml` ```yaml server: port: 8081 spring: datasource: url: jdbc:postgresql://localhost:5432/fitpub_instance2 username: postgres password: your_password jpa: hibernate: ddl-auto: validate fitpub: base-url: http://localhost:8081 domain: localhost:8081 logging: level: org.operaton.fitpub: DEBUG ``` ### Step 3: Build the Application ```bash mvn clean package -DskipTests ``` ## Running the Instances ### Terminal 1: Start Instance 1 ```bash java -jar target/feditrack-1.0-SNAPSHOT.jar --spring.profiles.active=instance1 ``` Wait for the application to start completely. You should see: ``` Started FitPubApplication in X.XXX seconds ``` ### Terminal 2: Start Instance 2 ```bash java -jar target/feditrack-1.0-SNAPSHOT.jar --spring.profiles.active=instance2 ``` ## Test Scenarios ### Test 1: User Registration **Instance 1 (http://localhost:8080)** 1. Navigate to http://localhost:8080/register 2. Register user: `alice` / `alice@localhost1.test` / `password123` 3. Login **Instance 2 (http://localhost:8081)** 1. Navigate to http://localhost:8081/register 2. Register user: `bob` / `bob@localhost2.test` / `password123` 3. Login ### Test 2: WebFinger Discovery **From Instance 1, discover Bob on Instance 2:** ```bash curl http://localhost:8080/.well-known/webfinger?resource=acct:bob@localhost:8081 ``` Expected response: ```json { "subject": "acct:bob@localhost:8081", "aliases": [ "http://localhost:8081/users/bob" ], "links": [ { "rel": "self", "type": "application/activity+json", "href": "http://localhost:8081/users/bob" } ] } ``` **From Instance 2, discover Alice on Instance 1:** ```bash curl http://localhost:8081/.well-known/webfinger?resource=acct:alice@localhost:8080 ``` ### Test 3: Remote User Discovery via UI **On Instance 1 (Alice following Bob):** 1. Login as Alice 2. Navigate to http://localhost:8080/discover 3. In the "Follow Remote Users" section, enter: `bob@localhost:8081` 4. Click "Search" 5. Verify Bob's profile appears with avatar, display name, and bio 6. Click "Follow" button 7. Verify notification appears: "Follow request sent to bob@localhost:8081" **Verify on Instance 2 (Bob's perspective):** 1. Login as Bob on http://localhost:8081 2. Check notifications - you should see: "alice@localhost:8080 followed you" 3. Navigate to http://localhost:8081/users/bob/followers 4. Verify alice@localhost:8080 appears in followers list ### Test 4: Following Relationship Check **Check via API:** ```bash # From Instance 2, check Bob's followers curl http://localhost:8081/api/users/bob/followers | jq # Expected: Alice should be in the list ``` **Check via UI:** On Instance 2: 1. Navigate to http://localhost:8081/users/bob 2. Check "Followers" count - should be 1 3. Click on "Followers" - Alice should be listed On Instance 1: 1. Navigate to http://localhost:8080/users/alice 2. Check "Following" count - should be 1 3. Click on "Following" - Bob should be listed ### Test 5: Activity Federation **Bob uploads a workout on Instance 2:** 1. Login as Bob on http://localhost:8081 2. Navigate to http://localhost:8081/upload 3. Upload a FIT file (use test file from `src/test/resources/`) 4. Set title: "Morning 10K Run" 5. Set visibility: "Public" 6. Click "Upload" **Verify on Instance 1 (Alice's federated timeline):** 1. Login as Alice on http://localhost:8080 2. Navigate to http://localhost:8080/timeline/federated 3. Verify Bob's "Morning 10K Run" activity appears with: - Federation badge: "🌐 Remote" - Bob's avatar and @bob@localhost:8081 - Map preview (if map image URL is available) - Metrics (distance, duration, pace, elevation) - Link to view on origin server ### Test 6: Remote Activity Details **Click on Remote Activity:** From Alice's federated timeline: 1. Click on Bob's "Morning 10K Run" activity title 2. Verify it opens Bob's activity on Instance 2 (http://localhost:8081/activities/{id}) in a new tab 3. Alternatively, click "View on Origin Server" button ### Test 7: Incoming Activity via ActivityPub **Test with manual ActivityPub POST:** ```bash # Create a test activity cat > test-activity.json <