using Microsoft.VisualStudio.TestTools.UnitTesting;
using System;
using System.IO;
using System.Text;
namespace FileLiberator.Tests;
///
/// What counts as a supplement having been downloaded. Reported in issue #1947: an Audible response that was
/// not the PDF was saved into the book's folder and the title recorded as having its PDF.
///
[TestClass]
public class DownloadPdfVerificationTests
{
private string directory = string.Empty;
[TestInitialize]
public void Initialize()
{
directory = Path.Combine(Path.GetTempPath(), $"libation-pdf-verify-tests-{Guid.NewGuid():N}");
Directory.CreateDirectory(directory);
}
[TestCleanup]
public void Cleanup()
{
try
{
Directory.Delete(directory, recursive: true);
}
catch (IOException)
{
// A leftover temp directory is not worth failing a test over.
}
}
private string Write(string fileName, byte[] contents)
{
var path = Path.Combine(directory, fileName);
File.WriteAllBytes(path, contents);
return path;
}
private string Write(string fileName, string contents) => Write(fileName, Encoding.UTF8.GetBytes(contents));
private static byte[] Pdf => Encoding.ASCII.GetBytes("%PDF-1.4\n1 0 obj\n<< >>\nendobj\n");
[TestMethod]
public void A_real_pdf_passes()
=> Assert.IsTrue(DownloadPdf.verifyDownload(Write("book.pdf", Pdf)).IsSuccess);
[TestMethod]
public void A_file_that_is_not_there_fails()
=> Assert.IsFalse(DownloadPdf.verifyDownload(Path.Combine(directory, "never-written.pdf")).IsSuccess);
[TestMethod]
public void An_empty_file_fails()
=> Assert.IsFalse(DownloadPdf.verifyDownload(Write("book.pdf", Array.Empty())).IsSuccess);
[TestMethod]
public void A_file_named_pdf_that_is_not_a_pdf_fails()
=> Assert.IsFalse(DownloadPdf.verifyDownload(Write("book.pdf", "Not a PDF at all")).IsSuccess);
///
/// The reported failure. Dinah's downloader renames by Content-Disposition, so an Audible JSON body does
/// not even arrive named .pdf and an extension check alone would wave it through.
///
[TestMethod]
public void An_audible_json_body_fails_whatever_it_is_named()
{
const string body = """{"asin":"B089T8FSK6","asset_details":[],"is_preview_enabled":false,"is_vvab":false}""";
Assert.IsFalse(DownloadPdf.verifyDownload(Write("book.json", body)).IsSuccess);
Assert.IsFalse(DownloadPdf.verifyDownload(Write("book.pdf", body)).IsSuccess);
}
[TestMethod]
public void A_json_body_behind_a_byte_order_mark_fails()
=> Assert.IsFalse(DownloadPdf.verifyDownload(Write("book.json", Encoding.UTF8.GetPreamble().Concat("""{"asin":"B089T8FSK6"}"""))).IsSuccess);
[TestMethod]
public void A_login_page_fails()
=> Assert.IsFalse(DownloadPdf.verifyDownload(Write("book.html", "Sign in")).IsSuccess);
///
/// A supplement is whatever its URL says it is, so a non-PDF one is only rejected when it looks like a
/// document Audible sent instead of the file. This is a zip's signature.
///
[TestMethod]
public void A_non_pdf_supplement_passes()
=> Assert.IsTrue(DownloadPdf.verifyDownload(Write("book.zip", [0x50, 0x4B, 0x03, 0x04, 0x14, 0x00])).IsSuccess);
}
file static class ByteExtensions
{
public static byte[] Concat(this byte[] first, string second)
=> [.. first, .. Encoding.UTF8.GetBytes(second)];
}