How to test BundleConfig - tdd

I have a problem with my bundles. Files .min is not being generated as reported on this link.
I have to create a test for it. How to do this?
[TestInitialize]
public void Setup()
{
BundleConfig.RegisterBundles(BundleTable.Bundles);
}
[TestMethod, Owner("Bundles")]
public void Deve_realizar_bundle_arquivos_min()
{
// Arrange
// Act
var bundle = BundleTable.Bundles.GetBundleFor("~/Scripts");
// Assert
// How to check if file "jquery.pnotify.min.js" is in bundle??
}

You can unit test bundles via the Optimizer/Optimization settings classes in the 1.1-beta1 package:
You will also need to implement a VirtualPathProvider if you want to truly unit test this, but then you should be able to do something like:
BundleCollection bundles = new BundleCollection();
OptimizationSettings config = new OptimizationSettings() {
ApplicationPath = TestContext.DeploymentDirectory,
BundleTable = BundleConfig.RegisterBundles(bundles)
};
BundleResponse response = Optimizer.BuildBundle("~/bundles/js", config);
Assert.IsNotNull(response);
Assert.AreEqual("alert(\"first\")", response.Content);
Assert.AreEqual(JsMinify.JsContentType, response.ContentType);
response = Optimizer.BuildBundle("~/bundles/css", config);
Assert.IsNotNull(response);
Assert.AreEqual("Css1{color:blue}", response.Content);
Assert.AreEqual(CssMinify.CssContentType, response.ContentType);

Related

Masstransit unti tests problem and ISendEndpointProvider within DI

I want to unit test services which uses Masstransit(rmq) to send messages. According to the doc, there is InMemoryTestHarness class for this. But I can't figure out how can I use it in my scenario.
I use AbpBoilerplate framework, so first of all I need to register Masstransit within Castle Windsor. For test module I do it smth like this:
var harness = new InMemoryTestHarness();
harness.Start().Wait(TimeSpan.FromSeconds(1));//harness.Bus is not null now
IocManager.IocContainer.Register(Component.For<InMemoryTestHarness>().Instance(harness));
IocManager.IocContainer.Register(Component.For<IBus, IBusControl>().Instance(harness.Bus));
Service I want to test is following:
public class ProcessingService
{
private readonly ProjectService _projectService;
//NOTE previously there was IBus interface...
private readonly ISendEndpointProvider _provider;
public ProcessingService(ISendEndpointProvider provider, [NotNull] ProjectService projectService )
{
_ProjectService = ProjectService ?? throw new ArgumentNullException(nameof(ProjectService));
_provider = provider;
}
public async Task ProcessFileAsync([NotNull] fileInput FileInput,
[NotNull] IUserProcessingSettings userProcessingSettings)
{
if (fileInput == null) throw new ArgumentNullException(nameof(fileInput));
if (userProcessingSettings == null) throw new ArgumentNullException(nameof(userProcessingSettings));
var entity = await _projectService.GetSomeEntityAsync();
ProcessFileCommand msg = new ProcessFileCommand(entity);
await _provider.Send(msg).ConfigureAwait(false);
}
}
The first problem with code above is that for now if I use ISendEndpointProvider instead of IBus as suggeted in the doc it is simply cannot resolve dependecies, no ISendEndpointProvider registered. And I'm not quite understand how to handle it within InMemoryTestHarness abstraction...
Here is the test method and consumer class:
[Fact]
public async Task Simple_Masstranist_Consumer_Test1()
{
//it was injected and started in ABP test module
var harness = Resolve<InMemoryTestHarness>();
//NOTE which one is correct option -- handler or consumer?
var consumerHarness = harness.Consumer<MyConsumer>();
// await harness.SubscribeHandler<MyConsumer>().ConfigureAwait(false);
try
{
var processingService = Resolve<ProcessingService>();
var emptyFileImput = FileInput.EmptyFileInput(1);
await ProcessingService.ProcessFileAsync(emptyFileImput).ConfigureAwait(false);
//NOTE test hangs on this command
consumerHarness.Consumed.Select<ProcessFileCommand>().Any().ShouldBeTrue();
// the consumer publish the event
harness.Published.Select<ProcessFileCommand>().Any().ShouldBeTrue();
}
finally
{
//already started...
await harness.Stop().ConfigureAwait(false);
}
}
public class MyConsumer : IConsumer<ProcessFileCommand>
{
public Task Consume(ConsumeContext<ProcessFileCommand> context)
{
context.Message.ShouldNotBeNull();
context.Message.EntityId.ShouldBe(1);
context.Message.FilePath.ShouldBe("some_path");
return Task.FromResult(true);
}
}
My expectations for InMemoryTestHarness is that it is a wrapper of InMemory bus suitable for tests, so when my service send some message, I expect that it would be reflected in proper structures of InMemoryTestHarness. When I've used IBus instead of ISendEndpointProvider test code simply hang on
consumerHarness.Consumed.Select().Any().ShouldBeTrue(); line of code. It seems that it blocks for some event which will neven occur.
So, my questions are:
Is it correct to use InMemoryTestHarness to mock message queue in my scenario, maybe I should configure manually InMemoryBus for that?
2)If I want to use ISendEndpointProvider within DI, what should I register?
Thanks in advance
Update:
var testHarness = new InMemoryTestHarness();
IocManager.IocContainer.Register(Component.For<InMemoryTestHarness>().UsingFactoryMethod(kernel =>
{
var busRegistrationContext = kernel.Resolve<IRegistration>();
testHarness.OnConfigureInMemoryBus +=
configurator => configurator.ConfigureEndpoints(busRegistrationContext);
return testHarness;
}).LifestyleSingleton());
You can use the built-in container configuration with the test harness, I've included an example of how to do it with Castle Windsor below. This will ensure all required types are registered in the container, including IBus, ISendEndpointProvider, and IPublishEndpoint.
You do not need to start the bus, the harness starts and creates it for you.
Also, do not access IBusControl prior to resolving and starting the test harness, or the BusControl property on the harness will not be initialized, returning null.
[Test]
public async Task Should_startup_the_container_with_the_harness()
{
var container = new WindsorContainer()
.Register(Component.For<InMemoryTestHarness>().UsingFactoryMethod(kernel =>
{
var testHarness = new InMemoryTestHarness();
var busRegistrationContext = kernel.Resolve<IBusRegistrationContext>();
testHarness.OnConfigureInMemoryBus += configurator => configurator.ConfigureEndpoints(busRegistrationContext);
return testHarness;
}).LifestyleSingleton())
.AddMassTransit(x =>
{
x.AddConsumer<PingConsumer>();
x.AddBus(context => context.GetRequiredService<InMemoryTestHarness>().BusControl);
});
var harness = container.Resolve<InMemoryTestHarness>();
await harness.Start();
try
{
var bus = container.Resolve<IBus>();
await bus.Publish(new PingMessage());
Assert.That(await harness.Consumed.Any<PingMessage>());
}
finally
{
await harness.Stop();
container.Dispose();
}
}
This won't setup Consumer, Saga, or other harnesses, but it will configure endpoints on the test harness.

Requesting Android permissions in a class (Xamarin)

I'm trying to request a permission at runtime for my app. I use a service provider to talk between the portable class and Android.
I start by calling this code on button press in the PCL:
using (new Busy(this))
{
var locationHelper = scope.Resolve<ILocationHelper>();
locationHelper.GetLocation(this);
}
This calls my Android level service:
public class AndroidLocationHelper : ILocationHelper, ILocationListener
{
readonly string[] PermissionsLocation =
{
Manifest.Permission.AccessCoarseLocation
};
const int RequestLocationId = 0;
public void GetLocation(SearchViewModel viewModel)
{
try
{
const string permission = Manifest.Permission.AccessCoarseLocation;
if (((int)Build.VERSION.SdkInt < 23) || (CheckSelfPermission(permission) == Permission.Granted))
{
}
else
RequestPermissions(PermissionsLocation, RequestLocationId);
}
catch (Exception ex)
{
Debug.WriteLine("Error while getting Location service");
Debug.WriteLine(ex.Message);
Messaging.AlertUser("There was an error with determining your location");
}
}
However, I get two errors on CheckSelfPermission and RequestPermissions. These two methods are only available to activities. The code works fine in MainActivity; however, I want to ask for permissions when the user hits a button, not in OnCreate or OnResume, etc.
Thanks for any help.
In your Android project, You can use this and use the Dependency Service to call it in Xamarin.Forms PCL project later:
var thisActivity = Forms.Context as Activity;
ActivityCompat.RequestPermissions(thisActivity, new string[] {
Manifest.Permission.AccessFineLocation }, 1);
ActivityCompat.RequestPermissions(thisActivity,
new String[] { Manifest.Permission.AccessFineLocation },
1);
You can try with ContextCompat.CheckSelfPermission, passing the application context, like this:
ContextCompat.CheckSelfPermission(Android.App.Application.Context, permission)
Update
In case of ActivityCompat.RequestPermissions, which requires an activity reference, you can keep track of the current activity. There is a very handy lib for that, called "CurrentActivityPlugin". You can find at https://github.com/jamesmontemagno/CurrentActivityPlugin
Rafael came up with a solution but I found another option that is a lot less effort just using MessagingCenter. In the MainActivity's OnCreate add a receiver that runs all the location code, that way you have access to all of the activities methods (and there are a bunch of tutorials on doing location services in MainActivity). Then add the Send inside of your service (the class).
To expound Rafael Steil's answer, I tried the suggested CurrentActivityPlugin and it worked on me. In my case I am trying to execute a voice call which needs CALL_PHONE permission. Here is the code snippet in your case: I used the ContextCompat & ActivityCompat so that I don't need to check the VERSION.SdkInt
using Plugin.CurrentActivity;
public void GetLocation(SearchViewModel viewModel){
var context = CrossCurrentActivity.Current.AppContext;
var activity = CrossCurrentActivity.Current.Activity;
int YOUR_ASSIGNED_REQUEST_CODE = 9;
if (ContextCompat.CheckSelfPermission(context, Manifest.Permission.AccessCoarseLocation) == (int)Android.Content.PM.Permission.Granted)
{
//Permission is granted, execute stuff
}
else
{
ActivityCompat.RequestPermissions(activity, new string[] { Manifest.Permission.AccessCoarseLocation }, YOUR_ASSIGNED_REQUEST_CODE);
}
}
It's dead simple
public bool CheckPermission()
{
const string permission = Manifest.Permission.ReceiveSms;
return ContextCompat.CheckSelfPermission(Forms.Context, permission) == (int) Permission.Granted;
}

How to use/setup TexturePacker2 libgdx

I have a difficulty with texturepacker2 from libgdx. I was trying to create textureAtlas using texturepakcer2 so that I can create animated images. However I could not use
TexturePacker2.process(Input Directory Path", "Output Directory Path", "texture_file");
Because it could not recognize TexturePacker2.
Even thought I import gdx-tool.jar file inside libs and also added libraries through
Project -> Properties -> Java Build Path -> Libraries -> Add jars, it still cannot resolve nor recognize the gdx-tool.jar.
How can I create texture atlas using TexturePakcer2? I heard there is a way to create using nightly-build from libgdx, how can I do it? When I unzip latest nightly-build there were so many jar, but I could only run setup-ui.
There are several ways. I used to take the way of implementing it into my Desktop application. Whenever i start it, the Atlas is generated. (If i changed something in it).
public class Main
{
public static void main(String[] args)
{
LwjglApplicationConfiguration cfg = new LwjglApplicationConfiguration();
cfg.title = "MyApp";
cfg.useGL20 = true;
cfg.fullscreen = false;
// switch for fullscreen
if (cfg.fullscreen)
{
cfg.width = Toolkit.getDefaultToolkit().getScreenSize().width;
cfg.height = Toolkit.getDefaultToolkit().getScreenSize().height;
}
else
{
cfg.width = 1280;
cfg.height = 720;
}
cfg.addIcon("data/appiconWindows.png", FileType.Internal);
// automatic packing of the textures and images and so on
Settings settings = new Settings();
settings.maxWidth = 2048;
settings.maxHeight = 2048;
settings.paddingX = 0;
settings.paddingY = 0;
TexturePacker2.process(settings, "directory with the files",
"output dir", "name of Atlas"); //third is outputdir
new LwjglApplication(new MainClass(), cfg);
}
}
Dont forget to add the tools lib to the Desktop project. gdx-tools.jar From the nightly or the Stable.
Else you can call it with the console. Like this:
java -cp gdx.jar;extensions/gdx-tools/gdx-tools.jar com.badlogic.gdx.tools.texturepacker.TexturePacker inputDir [outputDir] [packFileName]
Use TexturePacker from com.badlogic.gdx.tools.imagepacker.TexturePacker then create a class as below:
public class TextureSetup {
public static void main(String[] args) {
//TexturePacker; using default settings
TexturePacker.Settings packSettings = new TexturePacker.Settings();
TexturePacker.process(packSettings, "input-folder", "output-folder", "textures.pack");
}
}

How To: Caliburn.Micro.Autofac and Windows Phone

Is there and example, tutorial or anything that shows how to use Caliburn.Micro.Autofac with Windows Phone?
I created a basic application with Caliburn.Micro only, and that runs fine. Then I decided to use Caliburn.Micro.Autofac, so I derived my Bootstrapper from Caliburn.Micro.Autofac.AutofacBootstrapper and called base.Configure() inside the Bootstrapper Configure() method. Now wen I ran the application I get "The type 'AppBootstrapper' was not found." exception.
Appreciate any help.
This is the bootstrapper I wrote for a WP7 project. It's based on Caliburn.Micro.Autofac.AutofacBootstrapper but fixes some bugs.
public class AppBootstrapper : PhoneBootstrapper
{
private IContainer container;
protected void ConfigureContainer(ContainerBuilder builder)
{
// put any custom bindings here
}
#region Standard Autofac/Caliburn.Micro Bootstrapper
protected override void Configure()
{
// configure container
var builder = new ContainerBuilder();
// register phone services
var caliburnAssembly = AssemblySource.Instance.Union(new[] { typeof(IStorageMechanism).Assembly }).ToArray();
// register IStorageMechanism implementors
builder.RegisterAssemblyTypes(caliburnAssembly)
.Where(type => typeof(IStorageMechanism).IsAssignableFrom(type)
&& !type.IsAbstract
&& !type.IsInterface)
.As<IStorageMechanism>()
.SingleInstance();
// register IStorageHandler implementors
builder.RegisterAssemblyTypes(caliburnAssembly)
.Where(type => typeof(IStorageHandler).IsAssignableFrom(type)
&& !type.IsAbstract
&& !type.IsInterface)
.As<IStorageHandler>()
.SingleInstance();
// The constructor of these services must be called
// to attach to the framework properly.
var phoneService = new PhoneApplicationServiceAdapter(RootFrame);
var navigationService = new FrameAdapter(RootFrame, false);
builder.Register<IPhoneContainer>(c => new AutofacPhoneContainer(c)).SingleInstance();
builder.RegisterInstance<INavigationService>(navigationService).SingleInstance();
builder.RegisterInstance<IPhoneService>(phoneService).SingleInstance();
builder.Register<IEventAggregator>(c => new EventAggregator()).SingleInstance();
builder.Register<IWindowManager>(c => new WindowManager()).SingleInstance();
builder.Register<IVibrateController>(c => new SystemVibrateController()).SingleInstance();
builder.Register<ISoundEffectPlayer>(c => new XnaSoundEffectPlayer()).SingleInstance();
builder.RegisterType<StorageCoordinator>().AsSelf().SingleInstance();
builder.RegisterType<TaskController>().AsSelf().SingleInstance();
// allow derived classes to add to the container
ConfigureContainer(builder);
// build the container
container = builder.Build();
// start services
container.Resolve<StorageCoordinator>().Start();
container.Resolve<TaskController>().Start();
// add custom conventions for the phone
AddCustomConventions();
}
protected override object GetInstance(Type service, string key)
{
object instance;
if (string.IsNullOrEmpty(key))
{
if (container.TryResolve(service, out instance))
return instance;
}
else
{
if (container.TryResolveNamed(key, service, out instance))
return instance;
}
throw new Exception(string.Format("Could not locate any instances of contract {0}.", key ?? service.Name));
}
protected override IEnumerable<object> GetAllInstances(Type service)
{
return container.Resolve(typeof(IEnumerable<>).MakeGenericType(service)) as IEnumerable<object>;
}
protected override void BuildUp(object instance)
{
container.InjectProperties(instance);
}
private static void AddCustomConventions()
{
ConventionManager.AddElementConvention<Pivot>(Pivot.ItemsSourceProperty, "SelectedItem", "SelectionChanged").ApplyBinding =
(viewModelType, path, property, element, convention) =>
{
if (ConventionManager
.GetElementConvention(typeof(ItemsControl))
.ApplyBinding(viewModelType, path, property, element, convention))
{
ConventionManager
.ConfigureSelectedItem(element, Pivot.SelectedItemProperty, viewModelType, path);
ConventionManager
.ApplyHeaderTemplate(element, Pivot.HeaderTemplateProperty, viewModelType);
return true;
}
return false;
};
ConventionManager.AddElementConvention<Panorama>(Panorama.ItemsSourceProperty, "SelectedItem", "SelectionChanged").ApplyBinding =
(viewModelType, path, property, element, convention) =>
{
if (ConventionManager
.GetElementConvention(typeof(ItemsControl))
.ApplyBinding(viewModelType, path, property, element, convention))
{
ConventionManager
.ConfigureSelectedItem(element, Panorama.SelectedItemProperty, viewModelType, path);
ConventionManager
.ApplyHeaderTemplate(element, Panorama.HeaderTemplateProperty, viewModelType);
return true;
}
return false;
};
}
#endregion
}
EDIT I have created a fork of Caliburn.Micro.Autofac and fixed the issue on GitHub. Hopefully the pull request will be accepted and this will become part of the main repository.
For now, you can access the bootstrapper, and AutofacPhoneContainer from here - https://github.com/distantcam/Caliburn.Micro.Autofac/tree/master/src/Caliburn.Micro.Autofac-WP7
I have implemented a proper version (in my opinion) of Caliburn.Micro.Autofac for Windows Phone. You can download it and test project from my blog. The blog post is in Russian but you'll find the link to ZIP file in the top of the post. The code is too big to post here, so please take from the blog. I've send this to David Buksbaum (the author of Caliburn.Micro.Autofac). Hope he will incorporate it into his code base soon.
UPDATE
What is fixed:
Components realizing IPhoneService and INavigationService services must be instantiated before registering in container.
Realized component implementing IPhoneContainer. Without it you can't use Autofac in Caliburn.Micro.

Adding profile values for auto-generated user

I'm creating a ASP.NET MVC 3.0 website, and have a couple of different database initializations based on whether the site is intended for development, testing, or production. I'm stuck on the testing initialization, as I'm trying to get a test user created. I can get the user to create just fine, however when I try to add some profile values, I get: System.Web.HttpException: Request is not available in this context. Is there a way to add Profile values in a situation where the request isn't going to be available?
Following code is what is being run:
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
RegisterGlobalFilters(GlobalFilters.Filters);
RegisterRoutes(RouteTable.Routes);
if (ApplicationServices.GetInitialCatalog() != "tasktracker")
{
Database.SetInitializer(new TaskTrackerDropCreateDatabaseIfModelChanges());
}
else
{
Database.SetInitializer(new TaskTrackerCreateDatabaseIfNotExists());
}
using (var db = new TaskTrackerContext())
{
db.Database.Initialize(false);
}
}
public class TaskTrackerDropCreateDatabaseIfModelChanges : DropCreateDatabaseIfModelChanges<TaskTrackerContext>
{
protected override void Seed(TaskTrackerContext context)
{
// Set up the membership, roles, and profile systems.
ApplicationServices.InstallServices(SqlFeatures.Membership | SqlFeatures.Profile | SqlFeatures.RoleManager);
// Create the default accounts and roles.
if (ApplicationServices.GetInitialCatalog() == "tasktracker_testing")
{
if (Membership.GetUser("testuser", false) == null)
{
Membership.CreateUser("testuser", "password", "testuser#test.com");
MembershipUser user = Membership.GetUser("testuser", false);
user.IsApproved = true;
var profile = ProfileBase.Create("testuser");
profile.SetPropertyValue("FirstName", "test");
profile.SetPropertyValue("LastName", "user");
profile.SetPropertyValue("TimeZone", "US Mountain Standard Time");
profile.Save();
}
}
}
}
Interesting question. Have you looked at using the new Universal Providers? Dunno if you will run into the same httpcontext issue but may be worth a look: http://www.hanselman.com/blog/IntroducingSystemWebProvidersASPNETUniversalProvidersForSessionMembershipRolesAndUserProfileOnSQLCompactAndSQLAzure.aspx
Did you try to do a call of "Initialize()" :
profile.Initialize(username, true)
after your create action to see if the context should be Initialized.
By using Reflector i saw the ProfileBase of Initialize (see below) creates this kind of context from the settings:
public void Initialize(string username, bool isAuthenticated)
{
if (username != null)
{
this._UserName = username.Trim();
}
else
{
this._UserName = username;
}
SettingsContext context = new SettingsContext();
context.Add("UserName", this._UserName);
context.Add("IsAuthenticated", isAuthenticated);
this._IsAuthenticated = isAuthenticated;
base.Initialize(context, s_Properties, ProfileManager.Providers);
}
It seems working here, the SettingsContext() seems taking account of my custom properties declared in the web.config.
Regards,
I come back again because the solution I added with the "Initialize()" function in fact not run really after an other test. So in fact I found a way which runs correctly.
The problem of "request is not available in this context" in application_start in your case could be due to the application mode "Integrated" which is new from II7 instead of the Classic mode.
To see a good explain you ca go on the Mike Volodarsky's blog IIS7 Integrated mode: Request is not available in this context exception in Application_Start .
I copy/paste an extract which could indicate the main reason:
" *This error is due to a design change in the IIS7 Integrated pipeline that makes the request context unavailable in Application_Start event. When using the Classic mode (the only mode when running on previous versions of IIS), the request context used to be available, even though the Application_Start event has always been intended as a global and request-agnostic event in the application lifetime. Despite this, because ASP.NET applications were always started by the first request to the app, it used to be possible to get to the request context through the static HttpContext.Current field.* "
To solve this you can use a workaround that moves your first-request initialization from Application_Start to BeginRequest and performs the request-specific initialization on the first request.
A good example of code is done in his blog :
void Application_BeginRequest(Object source, EventArgs e)
{
HttpApplication app = (HttpApplication)source;
HttpContext context = app.Context;
// Attempt to peform first request initialization
FirstRequestInitialization.Initialize(context);
}
class FirstRequestInitialization
{
private static bool s_InitializedAlready = false;
private static Object s_lock = new Object();
// Initialize only on the first request
public static void Initialize(HttpContext context)
{
if (s_InitializedAlready)
{
return;
}
lock (s_lock)
{
if (s_InitializedAlready)
{
return;
}
// Perform first-request initialization here
//
// You can use your create profile code here....
//---
s_InitializedAlready = true;
}
}
}

Resources