mirror of
https://github.com/ajisaacs/OpenNest.git
synced 2026-11-14 03:25:07 -05:00
Nest Info filled a blank Made By with the current user every time it opened, so pressing OK on an existing nest's info (from a tab or Saved Nests) signed someone else's nest. The author is now stamped once when a nest is made (File > New, drawing set Make Nests, BOM import), and Nest Info shows the stored value as is, leaving a blank one blank. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
364 lines
12 KiB
C#
364 lines
12 KiB
C#
using System.Runtime.ExceptionServices;
|
|
using System.Windows.Forms;
|
|
using OpenNest.Forms;
|
|
|
|
namespace OpenNest.WinForms.Tests.Forms;
|
|
|
|
[Collection("Fill operation lifetime")]
|
|
public class EditNestInfoFormTests
|
|
{
|
|
[Fact]
|
|
public void ShownEditorOk_FileRoundTripPreservesUnchangedMaterialGradeAndDensity()
|
|
{
|
|
RunSta(() =>
|
|
{
|
|
using var files = new WindowsAcceptanceFiles();
|
|
var nest = AcceptanceNest();
|
|
|
|
AcceptShownEditor(nest, materialName: null);
|
|
|
|
Assert.Equal("Stainless", nest.Material.Name);
|
|
Assert.Equal("304", nest.Material.Grade);
|
|
Assert.Equal(0.289, nest.Material.Density);
|
|
var restored = files.RoundTrip(nest);
|
|
Assert.Equal("Stainless", restored.Material.Name);
|
|
Assert.Equal("304", restored.Material.Grade);
|
|
Assert.Equal(0.289, restored.Material.Density);
|
|
Assert.Equal("Acceptance nest", restored.Name);
|
|
});
|
|
}
|
|
|
|
[Fact]
|
|
public void ShownEditorOk_FileRoundTripClearsOldMetadataWhenMaterialNameChanges()
|
|
{
|
|
RunSta(() =>
|
|
{
|
|
using var files = new WindowsAcceptanceFiles();
|
|
var nest = AcceptanceNest();
|
|
|
|
AcceptShownEditor(nest, materialName: "Aluminum");
|
|
|
|
Assert.Equal("Aluminum", nest.Material.Name);
|
|
Assert.True(string.IsNullOrEmpty(nest.Material.Grade));
|
|
Assert.Equal(0, nest.Material.Density);
|
|
var restored = files.RoundTrip(nest);
|
|
Assert.Equal("Aluminum", restored.Material.Name);
|
|
Assert.True(string.IsNullOrEmpty(restored.Material.Grade));
|
|
Assert.Equal(0, restored.Material.Density);
|
|
Assert.Equal("Acceptance nest", restored.Name);
|
|
});
|
|
}
|
|
|
|
[Fact]
|
|
public void ThicknessBox_ReadsAPickedGauge_AndRejectsUnreadableText()
|
|
{
|
|
RunSta(() =>
|
|
{
|
|
using var form = new EditNestInfoForm();
|
|
var nest = AcceptanceNest();
|
|
form.LoadNestInfo(nest);
|
|
var thickness = (OpenNest.Controls.ThicknessComboBox)form.Controls.Find("thicknessBox", true).Single();
|
|
var apply = form.Controls.Find("applyButton", true).Single();
|
|
|
|
Assert.Equal("1/4\" - 0.25", thickness.Text);
|
|
thickness.SelectedItem = "16 ga - 0.0598";
|
|
Assert.Equal(0.0598, form.Thickness);
|
|
Assert.True(apply.Enabled);
|
|
|
|
thickness.Text = "sixteen";
|
|
Assert.False(apply.Enabled);
|
|
|
|
thickness.Text = "16ga";
|
|
form.SaveNestInfo(nest);
|
|
Assert.Equal(0.0598, nest.Thickness);
|
|
});
|
|
}
|
|
|
|
[Fact]
|
|
public void NewNestDefaultsChoice_NeedsTheOfferAndTheCheck()
|
|
{
|
|
RunSta(() =>
|
|
{
|
|
using var form = new EditNestInfoForm();
|
|
var box = (CheckBox)form.Controls.Find("useForNewNestsBox", true).Single();
|
|
|
|
box.Checked = true;
|
|
Assert.False(form.UseForNewNests);
|
|
|
|
form.OfferNewNestDefaults = true;
|
|
Assert.True(form.UseForNewNests);
|
|
|
|
box.Checked = false;
|
|
Assert.False(form.UseForNewNests);
|
|
});
|
|
}
|
|
|
|
private static Nest AcceptanceNest()
|
|
{
|
|
var nest = new Nest("Acceptance nest")
|
|
{
|
|
Material = new Material("Stainless", "304", 0.289),
|
|
Thickness = 0.25,
|
|
Units = Units.Inches,
|
|
};
|
|
nest.PlateDefaults.Size = new Geometry.Size(10, 20);
|
|
nest.CreatePlate();
|
|
return nest;
|
|
}
|
|
|
|
private static void AcceptShownEditor(Nest nest, string? materialName)
|
|
{
|
|
using var editor = new EditNestForm(nest);
|
|
editor.Show();
|
|
Assert.True(editor.Visible);
|
|
EditNestInfoForm? info = null;
|
|
Exception? failure = null;
|
|
var deadline = DateTime.UtcNow.AddSeconds(10);
|
|
using var accept = new System.Windows.Forms.Timer { Interval = 20 };
|
|
accept.Tick += (_, _) =>
|
|
{
|
|
info = Application.OpenForms.OfType<EditNestInfoForm>().SingleOrDefault();
|
|
if (info == null)
|
|
{
|
|
if (DateTime.UtcNow >= deadline)
|
|
throw new TimeoutException("The Nest Info editor was not shown.");
|
|
return;
|
|
}
|
|
|
|
accept.Stop();
|
|
try
|
|
{
|
|
Assert.True(info.Visible);
|
|
Assert.True(info.Modal);
|
|
if (materialName != null)
|
|
Assert.IsType<ComboBox>(info.Controls.Find("materialBox", true).Single()).Text = materialName;
|
|
info.EnableCheck();
|
|
var ok = Assert.IsType<Button>(info.Controls.Find("applyButton", true).Single());
|
|
Assert.True(ok.Enabled);
|
|
Assert.Equal(DialogResult.OK, ok.DialogResult);
|
|
ok.PerformClick();
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
failure = ex;
|
|
info.DialogResult = DialogResult.Cancel;
|
|
info.Close();
|
|
}
|
|
};
|
|
|
|
try
|
|
{
|
|
accept.Start();
|
|
// This is the live Nest Info entry point; it owns LoadNestInfo,
|
|
// ShowDialog and SaveNestInfo after the actual OK button accepts.
|
|
// An unchanged name never checks the server, so this completes without awaiting.
|
|
editor.ShowNestInfoEditorAsync().GetAwaiter().GetResult();
|
|
accept.Stop();
|
|
if (failure != null)
|
|
ExceptionDispatchInfo.Capture(failure).Throw();
|
|
Assert.NotNull(info);
|
|
Assert.Equal(DialogResult.OK, info.DialogResult);
|
|
Assert.False(info.Visible);
|
|
}
|
|
finally
|
|
{
|
|
accept.Stop();
|
|
info?.Dispose();
|
|
}
|
|
}
|
|
|
|
[Fact]
|
|
public void Name_IsReadOnlyUnlessRenameIsAllowed()
|
|
{
|
|
RunSta(() =>
|
|
{
|
|
var nest = AcceptanceNest();
|
|
using var form = new EditNestInfoForm();
|
|
form.LoadNestInfo(nest);
|
|
var nameBox = Assert.IsType<TextBox>(form.Controls.Find("nameBox", true).Single());
|
|
Assert.True(nameBox.ReadOnly);
|
|
|
|
form.AllowRename = true;
|
|
Assert.False(nameBox.ReadOnly);
|
|
nameBox.Text = " Renamed job ";
|
|
form.SaveNestInfo(nest);
|
|
|
|
Assert.Equal("Renamed job", nest.Name);
|
|
});
|
|
}
|
|
|
|
[Fact]
|
|
public void StatusList_FollowsWorkflowOrder_AndSavesDraft()
|
|
{
|
|
RunSta(() =>
|
|
{
|
|
var nest = AcceptanceNest();
|
|
using var form = new EditNestInfoForm();
|
|
form.LoadNestInfo(nest);
|
|
var statusBox = Assert.IsType<ComboBox>(form.Controls.Find("statusBox", true).Single());
|
|
|
|
Assert.Equal(NestStatuses.WorkflowOrder, statusBox.Items.Cast<NestStatus>());
|
|
|
|
form.Status = NestStatus.Draft;
|
|
form.SaveNestInfo(nest);
|
|
|
|
Assert.Equal(NestStatus.Draft, nest.Status);
|
|
});
|
|
}
|
|
|
|
[Fact]
|
|
public void BlankName_DisablesOk()
|
|
{
|
|
RunSta(() =>
|
|
{
|
|
using var form = new EditNestInfoForm { AllowRename = true };
|
|
form.LoadNestInfo(AcceptanceNest());
|
|
form.EnableCheck(); // The size box re-checks on a debounce timer.
|
|
var nameBox = Assert.IsType<TextBox>(form.Controls.Find("nameBox", true).Single());
|
|
var ok = Assert.IsType<Button>(form.Controls.Find("applyButton", true).Single());
|
|
Assert.True(ok.Enabled);
|
|
|
|
nameBox.Text = " ";
|
|
Assert.False(ok.Enabled);
|
|
nameBox.Text = "Job";
|
|
Assert.True(ok.Enabled);
|
|
});
|
|
}
|
|
|
|
[Fact]
|
|
public void SaveWithUnchangedMaterial_KeepsGradeAndDensity()
|
|
{
|
|
RunSta(() =>
|
|
{
|
|
var nest = new Nest { Material = new Material("Stainless", "304", 0.289) };
|
|
using var form = new EditNestInfoForm();
|
|
form.LoadNestInfo(nest);
|
|
|
|
form.SaveNestInfo(nest);
|
|
|
|
Assert.Equal("Stainless", nest.Material.Name);
|
|
Assert.Equal("304", nest.Material.Grade);
|
|
Assert.Equal(0.289, nest.Material.Density);
|
|
});
|
|
}
|
|
|
|
[Fact]
|
|
public void SaveWithChangedMaterial_GetsNameOnly()
|
|
{
|
|
RunSta(() =>
|
|
{
|
|
var nest = new Nest { Material = new Material("Stainless", "304", 0.289) };
|
|
using var form = new EditNestInfoForm();
|
|
form.LoadNestInfo(nest);
|
|
form.MaterialName = "Aluminum";
|
|
|
|
form.SaveNestInfo(nest);
|
|
|
|
Assert.Equal("Aluminum", nest.Material.Name);
|
|
Assert.True(string.IsNullOrEmpty(nest.Material.Grade));
|
|
Assert.Equal(0, nest.Material.Density);
|
|
});
|
|
}
|
|
|
|
[Fact]
|
|
public void GradeList_FollowsMaterial_AndSavesChosenGrade()
|
|
{
|
|
RunSta(() =>
|
|
{
|
|
var nest = new Nest { Material = new Material("Stainless", "304", 0.289) };
|
|
using var form = new EditNestInfoForm();
|
|
form.SetMaterialCatalog(new[]
|
|
{
|
|
new Data.MaterialConfig { Name = "Stainless", Grade = "316" },
|
|
new Data.MaterialConfig { Name = "Stainless", Grade = "304" },
|
|
new Data.MaterialConfig { Name = "Aluminum", Grade = "5052" },
|
|
});
|
|
form.LoadNestInfo(nest);
|
|
var gradeBox = Assert.IsType<ComboBox>(form.Controls.Find("gradeBox", true).Single());
|
|
|
|
Assert.Equal(new[] { "304", "316" }, gradeBox.Items.Cast<string>());
|
|
Assert.Equal("304", form.MaterialGrade);
|
|
|
|
form.MaterialName = "aluminum";
|
|
Assert.Equal(new[] { "5052" }, gradeBox.Items.Cast<string>());
|
|
Assert.Equal("", form.MaterialGrade);
|
|
|
|
form.MaterialGrade = "5052";
|
|
form.SaveNestInfo(nest);
|
|
|
|
Assert.Equal("Aluminum", nest.Material.Name);
|
|
Assert.Equal("5052", nest.Material.Grade);
|
|
Assert.Equal(0, nest.Material.Density);
|
|
});
|
|
}
|
|
|
|
[Fact]
|
|
public void SaveWithChangedGrade_KeepsNameAndDropsDensity()
|
|
{
|
|
RunSta(() =>
|
|
{
|
|
var nest = new Nest { Material = new Material("Stainless", "304", 0.289) };
|
|
using var form = new EditNestInfoForm();
|
|
form.LoadNestInfo(nest);
|
|
form.MaterialGrade = "316";
|
|
|
|
form.SaveNestInfo(nest);
|
|
|
|
Assert.Equal("Stainless", nest.Material.Name);
|
|
Assert.Equal("316", nest.Material.Grade);
|
|
Assert.Equal(0, nest.Material.Density);
|
|
});
|
|
}
|
|
|
|
[Fact]
|
|
public void NewNestMadeBy_StartsFromTheUserName_AndRemembersATypedName()
|
|
{
|
|
RunSta(() =>
|
|
{
|
|
var settings = Properties.Settings.Default;
|
|
var saved = settings.MadeBy;
|
|
try
|
|
{
|
|
settings.MadeBy = "";
|
|
Assert.Equal(Environment.UserName, NewNestFactory.DefaultMadeBy);
|
|
|
|
// Viewing an existing nest's info leaves a blank author blank.
|
|
var existing = new Nest();
|
|
using (var form = new EditNestInfoForm())
|
|
{
|
|
form.LoadNestInfo(existing);
|
|
Assert.Equal("", form.MadeBy);
|
|
form.SaveNestInfo(existing);
|
|
}
|
|
Assert.Equal("", existing.MadeBy);
|
|
Assert.Equal("", settings.MadeBy);
|
|
|
|
using (var form = new EditNestInfoForm())
|
|
{
|
|
form.LoadNestInfo(new Nest());
|
|
form.MadeBy = "Synthetic operator";
|
|
form.SaveNestInfo(new Nest());
|
|
}
|
|
Assert.Equal("Synthetic operator", settings.MadeBy);
|
|
Assert.Equal("Synthetic operator", NewNestFactory.DefaultMadeBy);
|
|
|
|
// A nest's own author is shown as is and, left alone, is not remembered.
|
|
using (var form = new EditNestInfoForm())
|
|
{
|
|
form.LoadNestInfo(new Nest { MadeBy = "Synthetic author" });
|
|
Assert.Equal("Synthetic author", form.MadeBy);
|
|
form.SaveNestInfo(new Nest());
|
|
}
|
|
Assert.Equal("Synthetic operator", settings.MadeBy);
|
|
}
|
|
finally
|
|
{
|
|
settings.MadeBy = saved;
|
|
}
|
|
});
|
|
}
|
|
|
|
private static void RunSta(Action action) =>
|
|
StaTestThread.Run(action, TimeSpan.FromSeconds(15), "The STA test did not complete.");
|
|
}
|