package de.danoeh.antennapod.core.service.download;

import android.os.Bundle;
import android.os.Parcel;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;

import java.util.ArrayList;

import de.danoeh.antennapod.model.feed.FeedFile;

import static org.junit.Assert.assertEquals;

@RunWith(RobolectricTestRunner.class)
public class DownloadRequestTest {

    @Test
    public void parcelInArrayListTest_WithAuth() {
        doTestParcelInArrayList("case has authentication",
                "usr1", "pass1", "usr2", "pass2");
    }

    @Test
    public void parcelInArrayListTest_NoAuth() {
        doTestParcelInArrayList("case no authentication",
                null, null, null, null);
    }

    @Test
    public void parcelInArrayListTest_MixAuth() {
        doTestParcelInArrayList("case mixed authentication",
                null, null, "usr2", "pass2");
    }

    // Test to ensure parcel using put/getParcelableArrayList() API work
    // based on: https://stackoverflow.com/a/13507191
    private void doTestParcelInArrayList(String message,
                                         String username1, String password1,
                                         String username2, String password2) {
        ArrayList<DownloadRequest> toParcel;
        { // test DownloadRequests to parcel
            String destStr = "file://location/media.mp3";
            FeedFile item1 = createFeedItem(1);
            Bundle arg1 = new Bundle();
            arg1.putString("arg1", "value1");
            DownloadRequest request1 = new DownloadRequest.Builder(destStr, item1, false)
                    .withAuthentication(username1, password1)
                    .withArguments(arg1)
                    .build();

            FeedFile item2 = createFeedItem(2);
            DownloadRequest request2 = new DownloadRequest.Builder(destStr, item2, true)
                    .withAuthentication(username2, password2)
                    .build();

            toParcel = new ArrayList<>();
            toParcel.add(request1);
            toParcel.add(request2);
        }

        // parcel the download requests
        Bundle bundleIn = new Bundle();
        bundleIn.putParcelableArrayList("r", toParcel);

        Parcel parcel = Parcel.obtain();
        bundleIn.writeToParcel(parcel, 0);

        Bundle bundleOut = new Bundle();
        bundleOut.setClassLoader(DownloadRequest.class.getClassLoader());
        parcel.setDataPosition(0); // to read the parcel from the beginning.
        bundleOut.readFromParcel(parcel);

        ArrayList<DownloadRequest> fromParcel = bundleOut.getParcelableArrayList("r");

        // spot-check contents to ensure they are the same
        // DownloadRequest.equals() implementation doesn't quite work
        // for DownloadRequest.argument (a Bundle)
        assertEquals(message + " - size", toParcel.size(), fromParcel.size());
        assertEquals(message + " - source", toParcel.get(1).getSource(), fromParcel.get(1).getSource());
        assertEquals(message + " - password", toParcel.get(0).getPassword(), fromParcel.get(0).getPassword());
        assertEquals(message + " - argument", toString(toParcel.get(0).getArguments()),
                toString(fromParcel.get(0).getArguments()));
    }

    private static String toString(Bundle b) {
        StringBuilder sb = new StringBuilder();
        sb.append("{");
        for (String key: b.keySet()) {
            Object val = b.get(key);
            sb.append("(").append(key).append(":").append(val).append(") ");
        }
        sb.append("}");
        return sb.toString();
    }

    private FeedFile createFeedItem(final int id) {
        // Use mockito would be less verbose, but it'll take extra 1 second for this tiny test
        return new FeedFile() {
            @Override
            public long getId() {
                return id;
            }

            @Override
            public String getDownload_url() {
                return "http://example.com/episode" + id;
            }

            @Override
            public int getTypeAsInt() {
                return 0;
            }

            @Override
            public String getHumanReadableIdentifier() {
                return "human-id-" + id;
            }
        };
    }
}

@@ -325,16 +325,64 @@
 tEquals;
+%0Aimport static org.junit.Assert.assertNotEquals;
 %0A%0A@RunWi
@@ -962,24 +962,1165 @@
 2%22);%0A    %7D%0A%0A
+    @Test%0A    public void downloadRequestTestEquals() %7B%0A        String destStr = %22file://location/media.mp3%22;%0A        String username = %22testUser%22;%0A        String password = %22testPassword%22;%0A        FeedFile item = createFeedItem(1);%0A        Bundle arg = new Bundle();%0A        arg.putString(%22arg1%22, %22value1%22);%0A        DownloadRequest request1 = new DownloadRequest.Builder(destStr, item, true)%0A                .deleteOnFailure(true)%0A                .withAuthentication(username, password)%0A                .withArguments(arg)%0A                .build();%0A%0A        DownloadRequest request2 = new DownloadRequest.Builder(destStr, item, true)%0A                .deleteOnFailure(true)%0A                .withAuthentication(username, password)%0A                .withArguments(arg)%0A                .build();%0A%0A        DownloadRequest request3 = new DownloadRequest.Builder(destStr, item, true)%0A                .deleteOnFailure(true)%0A                .withAuthentication(%22diffUsername%22, %22diffPassword%22)%0A                .withArguments(arg)%0A                .build();%0A%0A        assertEquals(request1, request2);%0A        assertNotEquals(request1, request3);%0A    %7D%0A%0A
     // Test 

Add new test for Download Request equals (#5183)