Merge lp:~mandel/ubuntuone-windows-installer/systray_integrate_update into lp:ubuntuone-windows-installer/beta

Proposed by Manuel de la Peña
Status: Merged
Merged at revision: 46
Proposed branch: lp:~mandel/ubuntuone-windows-installer/systray_integrate_update
Merge into: lp:ubuntuone-windows-installer/beta
Prerequisite: lp:~mandel/ubuntuone-windows-installer/systray_integrate_spring
Diff against target: 949 lines (+626/-75)
20 files modified
.bzrignore (+28/-54)
main.build (+8/-1)
src/Canonical.UbuntuOne.Client.Views/Canonical.UbuntuOne.Client.Views.csproj (+6/-0)
src/Canonical.UbuntuOne.Client.Views/NotifyIcon.xaml.cs (+2/-1)
src/Canonical.UbuntuOne.Client/Canonical.UbuntuOne.Client.csproj (+1/-0)
src/Canonical.UbuntuOne.Client/Notification/INotificationIconView.cs (+25/-0)
src/Canonical.UbuntuOne.Common.Tests/Update/UpdaterFixture.cs (+18/-0)
src/Canonical.UbuntuOne.Common/Update/IUpdateView.cs (+1/-1)
src/Canonical.UbuntuOne.Common/Update/Updater.cs (+20/-11)
src/Canonical.UbuntuOne.ProcessDispatcher/Canonical.UbuntuOne.ProcessDispatcher.csproj (+2/-0)
src/UbuntuOne.sln (+12/-0)
src/UbuntuOneClient.Tests/ProgramFixture.cs (+140/-0)
src/UbuntuOneClient.Tests/Properties/AssemblyInfo.cs (+36/-0)
src/UbuntuOneClient.Tests/UbuntuOneClient.Tests.csproj (+87/-0)
src/UbuntuOneClient/ApplicationWrapper.cs (+55/-0)
src/UbuntuOneClient/IApplication.cs (+41/-0)
src/UbuntuOneClient/Program.cs (+120/-7)
src/UbuntuOneClient/Properties/AssemblyInfo.cs (+2/-0)
src/UbuntuOneClient/UbuntuOneClient.csproj (+6/-0)
src/UbuntuOneClient/objects.xml (+16/-0)
To merge this branch: bzr merge lp:~mandel/ubuntuone-windows-installer/systray_integrate_update
Reviewer Review Type Date Requested Status
John Lenton (community) Approve
Vincenzo Di Somma (community) Approve
Review via email: mp+31167@code.launchpad.net

Description of the change

Provides the basics to allow the systray to auto-update.

To post a comment you must log in.
Revision history for this message
Vincenzo Di Somma (vds) :
review: Approve
Revision history for this message
Tim Cole (tcole) wrote :

Hmm. Why are we adding redundant entries to .bzrignore?

Revision history for this message
Manuel de la Peña (mandel) wrote :

> Hmm. Why are we adding redundant entries to .bzrignore?

You are right, that is strange, I'll take a look at the ignore file and will clean it up.

56. By Manuel de la Peña

Cleaned bzrignore.

57. By Manuel de la Peña

Merge with trunk.

Revision history for this message
John Lenton (chipaca) :
review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file '.bzrignore'
2--- .bzrignore 2010-07-27 15:02:26 +0000
3+++ .bzrignore 2010-07-30 09:47:43 +0000
4@@ -1,54 +1,28 @@
5-_ReSharper.Canonical.UbuntuOne.ProcessDispatcher
6-Canonical.UbuntuOne.ProcessDispatcher.5.0.ReSharper.user
7-bin
8-obj
9-bin
10-obj
11-bin
12-obj
13-bin
14-obj
15-bin
16-obj
17-Canonical.UbuntuOne.Common.csproj.ReSharper
18-bin
19-Canonical.UbuntuOne.ProcessDispatcher.5.0.ReSharper.user
20-Canonical.UbuntuOne.ProcessDispatcher.csproj.ReSharper
21-Canonical.UbuntuOne.ProcessDispatcher.Tests.csproj.ReSharper
22-Canonical.UbuntuOne.Client.su
23-Canonical.UbuntuOne.ProcessDispatcher.suo
24-Canonical.UbuntuOne.ProcessDispatcher.suo
25-Canonical.UbuntuOne.ProcessDispatcher.suo
26-Canonical.UbuntuOne.suo
27-_ReSharper.Canonical.UbuntuOne
28-Canonical.UbuntuOne.5.0.ReSharper.user
29-Canonical.UbuntuOne.Client.Views.csproj.user
30-test-results
31-Canonical.UbuntuOne.Client.pidb
32-Canonical.UbuntuOne.Common.pidb
33-Canonical.UbuntuOne.Common.Tests.pidb
34-Canonical.UbuntuOne.ProcessDispatcher.pidb
35-Canonical.UbuntuOne.ProcessDispatcher.Tests.pidb
36-UbuntuOne.sln.cache
37-UbuntuOne.userprefs
38-Canonical.UbuntuOne.Client.Views.pidb
39-_ReSharper.UbuntuOne
40-UbuntuOne.5.1.ReSharper.user
41-UbuntuOne.suo
42-Canonical.UbuntuOne.ProcessDispatcher.Tests.csproj.user
43-Canonical.UbuntuOne.ProcessDispatcher.csproj.user
44-tomboy.msi
45-tomboy.wxs
46-Tomboy.wixobj
47-UbuntuOne.msi
48-UbuntuOne.wixobj
49-UbuntuOne.wixpdb
50-tomboy
51-setup.exe
52-bin
53-obj
54-./bin
55-./bin
56-./obj
57-./bin
58-./obj
59+
60+install/UbuntuOne.wixobj
61+install/UbuntuOne.wixpdb
62+install/build_results
63+src/UbuntuOne.5.1.ReSharper.user
64+src/UbuntuOne.sln.cache
65+src/UbuntuOne.suo
66+src/_ReSharper.UbuntuOne
67+src/Canonical.UbuntuOne.Client/bin
68+src/Canonical.UbuntuOne.Client/obj
69+src/Canonical.UbuntuOne.Client.Test/obj
70+src/Canonical.UbuntuOne.Client.Test/bin
71+src/Canonical.UbuntuOne.Client.Views/bin
72+src/Canonical.UbuntuOne.Client.Views/obj
73+src/Canonical.UbuntuOne.Common/bin
74+src/Canonical.UbuntuOne.Common/obj
75+src/Canonical.UbuntuOne.Common.Tests/obj
76+src/Canonical.UbuntuOne.Common.Tests/bin
77+src/Canonical.UbuntuOne.ProcessDispatcher/bin
78+src/Canonical.UbuntuOne.ProcessDispatcher/obj
79+src/Canonical.UbuntuOne.ProcessDispatcher.Tests/obj
80+src/Canonical.UbuntuOne.ProcessDispatcher.Tests/bin
81+src/ServiceTestApp/bin
82+src/ServiceTestApp/obj
83+src/UbuntuOneClient/bin
84+src/UbuntuOneClient/obj
85+src/UbuntuOneClient.Tests/bin
86+src/UbuntuOneClient.Tests/obj
87
88=== modified file 'main.build'
89--- main.build 2010-07-28 09:04:19 +0000
90+++ main.build 2010-07-30 09:47:43 +0000
91@@ -135,13 +135,20 @@
92 workingdir="src/Canonical.UbuntuOne.ProcessDispatcher.Tests/bin/${enviroment}"
93 program="nunit-console.exe"
94 commandline="Canonical.UbuntuOne.ProcessDispatcher.Tests.dll /xml=../../../../test-results/Canonical.UbuntuOne.ProcessDispatcher.Tests-Result.xml" />
95-
96+
97 <echo>Canonical.UbuntuOne.Client.Test</echo>
98 <exec basedir="tools/NUnit"
99 managed="true"
100 workingdir="src/Canonical.UbuntuOne.Client.Test/bin/${enviroment}"
101 program="nunit-console.exe"
102 commandline="Canonical.UbuntuOne.Client.Test.dll /xml=../../../../test-results/Canonical.UbuntuOne.Client.Test-Result.xml" />
103+
104+ <echo>UbuntuOneClient.Tests</echo>
105+ <exec basedir="tools/NUnit"
106+ managed="true"
107+ workingdir="src/UbuntuOneClient.Tests/bin/${enviroment}"
108+ program="nunit-console.exe"
109+ commandline="UbuntuOneClient.Tests.dll /xml=../../../../test-results/UbuntuOneClient.Tests-Result.xml" />
110 </target>
111
112 <target name="installer"
113
114=== modified file 'src/Canonical.UbuntuOne.Client.Views/Canonical.UbuntuOne.Client.Views.csproj'
115--- src/Canonical.UbuntuOne.Client.Views/Canonical.UbuntuOne.Client.Views.csproj 2010-07-27 16:03:23 +0000
116+++ src/Canonical.UbuntuOne.Client.Views/Canonical.UbuntuOne.Client.Views.csproj 2010-07-30 09:47:43 +0000
117@@ -181,6 +181,12 @@
118 <Resource Include="Resources\ubuntu-logo-32x32.png">
119 </Resource>
120 </ItemGroup>
121+ <ItemGroup>
122+ <ProjectReference Include="..\Canonical.UbuntuOne.Client\Canonical.UbuntuOne.Client.csproj">
123+ <Project>{7467483A-D6D5-4362-8DF4-57A7254EB569}</Project>
124+ <Name>Canonical.UbuntuOne.Client</Name>
125+ </ProjectReference>
126+ </ItemGroup>
127 <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
128 <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
129 Other similar extension points exist, see Microsoft.Common.targets.
130
131=== modified file 'src/Canonical.UbuntuOne.Client.Views/NotifyIcon.xaml.cs'
132--- src/Canonical.UbuntuOne.Client.Views/NotifyIcon.xaml.cs 2010-07-27 15:02:26 +0000
133+++ src/Canonical.UbuntuOne.Client.Views/NotifyIcon.xaml.cs 2010-07-30 09:47:43 +0000
134@@ -18,13 +18,14 @@
135 * Authors: Manuel de la Peña <manuel.delapena@canonical.com>
136 */
137 using System.Windows;
138+using Canonical.UbuntuOne.Client.Notification;
139
140 namespace Canonical.UbuntuOne.Client.Views
141 {
142 /// <summary>
143 /// Interaction logic for UbuntuOneNotifyIcon.xaml
144 /// </summary>
145- public partial class UbuntuOneNotifyIcon : Window
146+ public partial class UbuntuOneNotifyIcon : Window, INotificationIconView
147 {
148 public UbuntuOneNotifyIcon()
149 {
150
151=== modified file 'src/Canonical.UbuntuOne.Client/Canonical.UbuntuOne.Client.csproj'
152--- src/Canonical.UbuntuOne.Client/Canonical.UbuntuOne.Client.csproj 2010-07-27 15:02:26 +0000
153+++ src/Canonical.UbuntuOne.Client/Canonical.UbuntuOne.Client.csproj 2010-07-30 09:47:43 +0000
154@@ -32,6 +32,7 @@
155 <ConsolePause>false</ConsolePause>
156 </PropertyGroup>
157 <ItemGroup>
158+ <Compile Include="Notification\INotificationIconView.cs" />
159 <Compile Include="Notification\NotificationIconPresenter.cs" />
160 <Compile Include="Notification\OperationCompletenessEventArgs.cs" />
161 <Compile Include="Notification\RecentlyModifiedEventArgs.cs" />
162
163=== added file 'src/Canonical.UbuntuOne.Client/Notification/INotificationIconView.cs'
164--- src/Canonical.UbuntuOne.Client/Notification/INotificationIconView.cs 1970-01-01 00:00:00 +0000
165+++ src/Canonical.UbuntuOne.Client/Notification/INotificationIconView.cs 2010-07-30 09:47:43 +0000
166@@ -0,0 +1,25 @@
167+/**
168+ * Copyright 2010 Canonical Ltd.
169+ *
170+ * This file is part of UbuntuOne on Windows.
171+ *
172+ * UbuntuOne on Windows is free software: you can redistribute it and/or modify
173+ * it under the terms of the GNU Lesser General Public License version
174+ * as published by the Free Software Foundation.
175+ *
176+ * Ubuntu One on Windows is distributed in the hope that it will be useful,
177+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
178+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
179+ * GNU Lesser General Public License for more details.
180+ *
181+ * You should have received a copy of the GNU Lesser General Public License
182+ * along with UbuntuOne for Windows. If not, see <http://www.gnu.org/licenses/>.
183+ *
184+ * Authors: Manuel de la Peña <manuel.delapena@canonical.com>
185+ */
186+namespace Canonical.UbuntuOne.Client.Notification
187+{
188+ public interface INotificationIconView
189+ {
190+ }
191+}
192
193=== modified file 'src/Canonical.UbuntuOne.Common.Tests/Update/UpdaterFixture.cs'
194--- src/Canonical.UbuntuOne.Common.Tests/Update/UpdaterFixture.cs 2010-07-21 10:07:22 +0000
195+++ src/Canonical.UbuntuOne.Common.Tests/Update/UpdaterFixture.cs 2010-07-30 09:47:43 +0000
196@@ -193,6 +193,24 @@
197 }
198 }
199
200+ [Test]
201+ [ExpectedException(typeof(SelfUpdateException))]
202+ public void CheckForUpdatesExceptionTest()
203+ {
204+ using(_mocks.Record())
205+ {
206+ Expect.Call(_dotUpdaterWrapper.CheckForUpdates())
207+ .Throw(new UpdaterException(""));
208+ }
209+ using(_mocks.Playback())
210+ {
211+ if (_updater.UpdatesArePresent())
212+ {
213+ _updater.PerformUpdate();
214+ }
215+ }
216+ }
217+
218 #endregion
219 }
220 }
221
222=== modified file 'src/Canonical.UbuntuOne.Common/Update/IUpdateView.cs'
223--- src/Canonical.UbuntuOne.Common/Update/IUpdateView.cs 2010-07-14 13:50:36 +0000
224+++ src/Canonical.UbuntuOne.Common/Update/IUpdateView.cs 2010-07-30 09:47:43 +0000
225@@ -32,7 +32,7 @@
226 /// and return if he decided to update the application or not.
227 /// </summary>
228 /// <returns>The answer that the user provided.</returns>
229- UpdateConfirmation AskForDownloadConfirmation();
230+ UpdateConfirmation AskForDownloadAndUpdateConfirmation();
231
232 /// <summary>
233 /// This method should prompt some kind of confirmation to the user to close and install the update
234
235=== modified file 'src/Canonical.UbuntuOne.Common/Update/Updater.cs'
236--- src/Canonical.UbuntuOne.Common/Update/Updater.cs 2010-07-21 10:07:22 +0000
237+++ src/Canonical.UbuntuOne.Common/Update/Updater.cs 2010-07-30 09:47:43 +0000
238@@ -160,34 +160,43 @@
239
240 public bool UpdatesArePresent()
241 {
242- // we lock since this is done in a multithreaded enviroment and
243- // we want to make sure that we do not check for the update twice at the same time
244- if(_task == null)
245+ try
246 {
247- lock (_updateLock)
248+ // we lock since this is done in a multithreaded enviroment and
249+ // we want to make sure that we do not check for the update twice at the same time
250+ if (_task == null)
251 {
252- _task = DotUpdater.CheckForUpdates();
253- _updateChecked = true;
254+ lock (_updateLock)
255+ {
256+ _task = DotUpdater.CheckForUpdates();
257+ _updateChecked = true;
258+ }
259 }
260- }
261- return _task != null;
262+ return _task != null;
263+ }
264+ catch(UpdaterException ex)
265+ {
266+ throw new SelfUpdateException("Could not check for updates.", ex);
267+ }
268 }
269
270 public void PerformUpdate()
271 {
272 lock (_updateLock)
273 {
274+ // ask the user if he wants to perform the update
275+ if (UpdateView.AskForDownloadAndUpdateConfirmation() == UpdateConfirmation.NO) return;
276 if (!_updateChecked)
277 {
278 Logger.Error(UpdateResources.CheckNotDone);
279 throw new SelfUpdateException(UpdateResources.CheckNotDone);
280 }
281- if(_task == null)
282+ if (_task == null)
283 {
284 Logger.Error(UpdateResources.NoUpdatesAvailable);
285 throw new SelfUpdateException(UpdateResources.NoUpdatesAvailable);
286 }
287- if(!_task.Downloaded && !_downloadingUpdate)
288+ if (!_task.Downloaded && !_downloadingUpdate)
289 {
290 // we need to download the update
291 try
292@@ -212,7 +221,7 @@
293 throw new SelfUpdateException(UpdateResources.CannotDownload, e);
294 }
295 }
296- if(_task.Downloaded)
297+ if (_task.Downloaded)
298 {
299 _downloadingUpdate = false;
300 // just call the handler directly
301
302=== modified file 'src/Canonical.UbuntuOne.ProcessDispatcher/Canonical.UbuntuOne.ProcessDispatcher.csproj'
303--- src/Canonical.UbuntuOne.ProcessDispatcher/Canonical.UbuntuOne.ProcessDispatcher.csproj 2010-07-26 16:01:28 +0000
304+++ src/Canonical.UbuntuOne.ProcessDispatcher/Canonical.UbuntuOne.ProcessDispatcher.csproj 2010-07-30 09:47:43 +0000
305@@ -29,6 +29,7 @@
306 <IsWebBootstrapper>false</IsWebBootstrapper>
307 <UseApplicationTrust>false</UseApplicationTrust>
308 <BootstrapperEnabled>true</BootstrapperEnabled>
309+ <TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
310 </PropertyGroup>
311 <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
312 <DebugSymbols>true</DebugSymbols>
313@@ -121,6 +122,7 @@
314 <HintPath>..\..\lib\Protobuf-net\protobuf-net.dll</HintPath>
315 </Reference>
316 <Reference Include="System.Core">
317+ <RequiredTargetFramework>3.5</RequiredTargetFramework>
318 </Reference>
319 <Reference Include="System.Xml" />
320 </ItemGroup>
321
322=== modified file 'src/UbuntuOne.sln'
323--- src/UbuntuOne.sln 2010-07-27 15:02:26 +0000
324+++ src/UbuntuOne.sln 2010-07-30 09:47:43 +0000
325@@ -19,6 +19,8 @@
326 EndProject
327 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UbuntuOneClient", "UbuntuOneClient\UbuntuOneClient.csproj", "{E41083CC-B99A-4AEC-93CC-F693F6AA6071}"
328 EndProject
329+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UbuntuOneClient.Tests", "UbuntuOneClient.Tests\UbuntuOneClient.Tests.csproj", "{53B3D3DA-687D-4D35-A3D3-7939E635098B}"
330+EndProject
331 Global
332 GlobalSection(SolutionConfigurationPlatforms) = preSolution
333 Debug|Any CPU = Debug|Any CPU
334@@ -119,6 +121,16 @@
335 {E41083CC-B99A-4AEC-93CC-F693F6AA6071}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
336 {E41083CC-B99A-4AEC-93CC-F693F6AA6071}.Release|Mixed Platforms.Build.0 = Release|Any CPU
337 {E41083CC-B99A-4AEC-93CC-F693F6AA6071}.Release|x86.ActiveCfg = Release|Any CPU
338+ {53B3D3DA-687D-4D35-A3D3-7939E635098B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
339+ {53B3D3DA-687D-4D35-A3D3-7939E635098B}.Debug|Any CPU.Build.0 = Debug|Any CPU
340+ {53B3D3DA-687D-4D35-A3D3-7939E635098B}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
341+ {53B3D3DA-687D-4D35-A3D3-7939E635098B}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
342+ {53B3D3DA-687D-4D35-A3D3-7939E635098B}.Debug|x86.ActiveCfg = Debug|Any CPU
343+ {53B3D3DA-687D-4D35-A3D3-7939E635098B}.Release|Any CPU.ActiveCfg = Release|Any CPU
344+ {53B3D3DA-687D-4D35-A3D3-7939E635098B}.Release|Any CPU.Build.0 = Release|Any CPU
345+ {53B3D3DA-687D-4D35-A3D3-7939E635098B}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
346+ {53B3D3DA-687D-4D35-A3D3-7939E635098B}.Release|Mixed Platforms.Build.0 = Release|Any CPU
347+ {53B3D3DA-687D-4D35-A3D3-7939E635098B}.Release|x86.ActiveCfg = Release|Any CPU
348 EndGlobalSection
349 GlobalSection(SolutionProperties) = preSolution
350 HideSolutionNode = FALSE
351
352=== added directory 'src/UbuntuOneClient.Tests'
353=== added file 'src/UbuntuOneClient.Tests/ProgramFixture.cs'
354--- src/UbuntuOneClient.Tests/ProgramFixture.cs 1970-01-01 00:00:00 +0000
355+++ src/UbuntuOneClient.Tests/ProgramFixture.cs 2010-07-30 09:47:43 +0000
356@@ -0,0 +1,140 @@
357+/**
358+ * Copyright 2010 Canonical Ltd.
359+ *
360+ * This file is part of UbuntuOne on Windows.
361+ *
362+ * UbuntuOne on Windows is free software: you can redistribute it and/or modify
363+ * it under the terms of the GNU Lesser General Public License version
364+ * as published by the Free Software Foundation.
365+ *
366+ * Ubuntu One on Windows is distributed in the hope that it will be useful,
367+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
368+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
369+ * GNU Lesser General Public License for more details.
370+ *
371+ * You should have received a copy of the GNU Lesser General Public License
372+ * along with UbuntuOne for Windows. If not, see <http://www.gnu.org/licenses/>.
373+ *
374+ * Authors: Manuel de la Peña <manuel.delapena@canonical.com>
375+ */
376+using System.Windows;
377+using Canonical.UbuntuOne.Client.Notification;
378+using Canonical.UbuntuOne.Common.Update;
379+using NUnit.Framework;
380+using Rhino.Mocks;
381+
382+namespace UbuntuOneClient.Tests
383+{
384+ [TestFixture]
385+ public class ProgramFixture
386+ {
387+ // TODO: If this tests are ran in TestDriven.net there are exceptions thrown
388+ // due to the way in which the threads are spawn. If the tests are ran with NUnit
389+ // there are no issues.
390+ #region Variables
391+
392+ private IUpdater _updater;
393+ private INotificationIconView _notifyIcon;
394+ private IApplication _app;
395+ private MockRepository _mocks;
396+ private Program _program;
397+
398+ #endregion
399+
400+ #region Seup & Tear Down
401+
402+ [SetUp]
403+ public void Setup()
404+ {
405+ _mocks = new MockRepository();
406+ _updater = _mocks.StrictMock<IUpdater>();
407+ _notifyIcon = _mocks.StrictMock<INotificationIconView>();
408+ _app = _mocks.StrictMock<IApplication>();
409+ _program = new Program
410+ {
411+ NotifyIcon = _notifyIcon,
412+ Updater = _updater,
413+ Application = _app
414+ };
415+ }
416+
417+ [TearDown]
418+ public void TearDown()
419+ {
420+ // ensure that the updater thread joins the application, if not we will have an issue
421+ // with the tests since the thread will not be collected
422+ _program.StopUpdaterThread();
423+ }
424+
425+ #endregion
426+
427+ [Test]
428+ public void StartApplicationNoUpdates()
429+ {
430+ using(_mocks.Record())
431+ {
432+ // expect the application shutdown mode to change
433+ _app.ShutdownMode = ShutdownMode.OnExplicitShutdown;
434+
435+ // expect that we are calling the run with the correct window
436+ Expect.Call(() => _app.Run(_notifyIcon))
437+ .Repeat.Once();
438+
439+ // return that the are no update, since we have a strict mock the test will
440+ // fail if we perform the update.
441+ Expect.Call(_updater.UpdatesArePresent())
442+ .Return(false);
443+ }
444+ using(_mocks.Playback())
445+ {
446+ _program.StartApplication();
447+ }
448+ }
449+
450+ [Test]
451+ public void StartApplicationWithUpdates()
452+ {
453+ using (_mocks.Record())
454+ {
455+ _app.ShutdownMode = ShutdownMode.OnExplicitShutdown;
456+
457+ // expect that we are calling the run with the correct window
458+ Expect.Call(() => _app.Run(_notifyIcon))
459+ .Repeat.Once();
460+
461+ // return that the are no update, since we have a strict mock the test will
462+ // fail if we perform the update.
463+ Expect.Call(_updater.UpdatesArePresent())
464+ .Return(true);
465+
466+ Expect.Call(() => _updater.PerformUpdate());
467+ }
468+ using(_mocks.Playback())
469+ {
470+ _program.StartApplication();
471+ }
472+ }
473+
474+ [Test]
475+ public void StartApplicationWithCheckUpdatesExceptionTest()
476+ {
477+ using(_mocks.Record())
478+ {
479+ _app.ShutdownMode = ShutdownMode.OnExplicitShutdown;
480+
481+ // expect that we are calling the run with the correct window
482+ Expect.Call(() => _app.Run(_notifyIcon))
483+ .Repeat.Once();
484+
485+ // throw an exception and expect it to be caught and continue.
486+ Expect.Call(_updater.UpdatesArePresent())
487+ .Throw(new SelfUpdateException());
488+
489+ }
490+ using(_mocks.Playback())
491+ {
492+ _program.StartApplication();
493+ }
494+ }
495+ }
496+}
497
498=== added directory 'src/UbuntuOneClient.Tests/Properties'
499=== added file 'src/UbuntuOneClient.Tests/Properties/AssemblyInfo.cs'
500--- src/UbuntuOneClient.Tests/Properties/AssemblyInfo.cs 1970-01-01 00:00:00 +0000
501+++ src/UbuntuOneClient.Tests/Properties/AssemblyInfo.cs 2010-07-30 09:47:43 +0000
502@@ -0,0 +1,36 @@
503+using System.Reflection;
504+using System.Runtime.CompilerServices;
505+using System.Runtime.InteropServices;
506+
507+// General Information about an assembly is controlled through the following
508+// set of attributes. Change these attribute values to modify the information
509+// associated with an assembly.
510+[assembly: AssemblyTitle("UbuntuOneClient.Tests")]
511+[assembly: AssemblyDescription("")]
512+[assembly: AssemblyConfiguration("")]
513+[assembly: AssemblyCompany("")]
514+[assembly: AssemblyProduct("UbuntuOneClient.Tests")]
515+[assembly: AssemblyCopyright("Copyright © 2010")]
516+[assembly: AssemblyTrademark("")]
517+[assembly: AssemblyCulture("")]
518+
519+// Setting ComVisible to false makes the types in this assembly not visible
520+// to COM components. If you need to access a type in this assembly from
521+// COM, set the ComVisible attribute to true on that type.
522+[assembly: ComVisible(false)]
523+
524+// The following GUID is for the ID of the typelib if this project is exposed to COM
525+[assembly: Guid("007ab11d-53f0-4edd-8044-f6aaba73ac6c")]
526+
527+// Version information for an assembly consists of the following four values:
528+//
529+// Major Version
530+// Minor Version
531+// Build Number
532+// Revision
533+//
534+// You can specify all the values or you can default the Build and Revision Numbers
535+// by using the '*' as shown below:
536+// [assembly: AssemblyVersion("1.0.*")]
537+[assembly: AssemblyVersion("1.0.0.0")]
538+[assembly: AssemblyFileVersion("1.0.0.0")]
539
540=== added file 'src/UbuntuOneClient.Tests/UbuntuOneClient.Tests.csproj'
541--- src/UbuntuOneClient.Tests/UbuntuOneClient.Tests.csproj 1970-01-01 00:00:00 +0000
542+++ src/UbuntuOneClient.Tests/UbuntuOneClient.Tests.csproj 2010-07-30 09:47:43 +0000
543@@ -0,0 +1,87 @@
544+<?xml version="1.0" encoding="utf-8"?>
545+<Project ToolsVersion="3.5" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
546+ <PropertyGroup>
547+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
548+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
549+ <ProductVersion>9.0.21022</ProductVersion>
550+ <SchemaVersion>2.0</SchemaVersion>
551+ <ProjectGuid>{53B3D3DA-687D-4D35-A3D3-7939E635098B}</ProjectGuid>
552+ <OutputType>Library</OutputType>
553+ <AppDesignerFolder>Properties</AppDesignerFolder>
554+ <RootNamespace>UbuntuOneClient.Tests</RootNamespace>
555+ <AssemblyName>UbuntuOneClient.Tests</AssemblyName>
556+ <TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
557+ <FileAlignment>512</FileAlignment>
558+ </PropertyGroup>
559+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
560+ <DebugSymbols>true</DebugSymbols>
561+ <DebugType>full</DebugType>
562+ <Optimize>false</Optimize>
563+ <OutputPath>bin\Debug\</OutputPath>
564+ <DefineConstants>DEBUG;TRACE</DefineConstants>
565+ <ErrorReport>prompt</ErrorReport>
566+ <WarningLevel>4</WarningLevel>
567+ </PropertyGroup>
568+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
569+ <DebugType>pdbonly</DebugType>
570+ <Optimize>true</Optimize>
571+ <OutputPath>bin\Release\</OutputPath>
572+ <DefineConstants>TRACE</DefineConstants>
573+ <ErrorReport>prompt</ErrorReport>
574+ <WarningLevel>4</WarningLevel>
575+ </PropertyGroup>
576+ <ItemGroup>
577+ <Reference Include="nunit.framework, Version=2.5.5.10112, Culture=neutral, PublicKeyToken=96d09a1eb7f44a77, processorArchitecture=MSIL">
578+ <SpecificVersion>False</SpecificVersion>
579+ <HintPath>..\..\lib\Nunit\nunit.framework.dll</HintPath>
580+ </Reference>
581+ <Reference Include="PresentationFramework">
582+ <RequiredTargetFramework>3.0</RequiredTargetFramework>
583+ </Reference>
584+ <Reference Include="Rhino.Mocks, Version=3.6.0.0, Culture=neutral, PublicKeyToken=0b3305902db7183f, processorArchitecture=MSIL">
585+ <SpecificVersion>False</SpecificVersion>
586+ <HintPath>..\..\lib\RhinoMocks\Rhino.Mocks.dll</HintPath>
587+ </Reference>
588+ <Reference Include="System" />
589+ <Reference Include="System.Core">
590+ <RequiredTargetFramework>3.5</RequiredTargetFramework>
591+ </Reference>
592+ <Reference Include="System.Xml.Linq">
593+ <RequiredTargetFramework>3.5</RequiredTargetFramework>
594+ </Reference>
595+ <Reference Include="System.Data.DataSetExtensions">
596+ <RequiredTargetFramework>3.5</RequiredTargetFramework>
597+ </Reference>
598+ <Reference Include="System.Data" />
599+ <Reference Include="System.Xml" />
600+ <Reference Include="WindowsBase">
601+ <RequiredTargetFramework>3.0</RequiredTargetFramework>
602+ </Reference>
603+ </ItemGroup>
604+ <ItemGroup>
605+ <Compile Include="ProgramFixture.cs" />
606+ <Compile Include="Properties\AssemblyInfo.cs" />
607+ </ItemGroup>
608+ <ItemGroup>
609+ <ProjectReference Include="..\Canonical.UbuntuOne.Client\Canonical.UbuntuOne.Client.csproj">
610+ <Project>{7467483A-D6D5-4362-8DF4-57A7254EB569}</Project>
611+ <Name>Canonical.UbuntuOne.Client</Name>
612+ </ProjectReference>
613+ <ProjectReference Include="..\Canonical.UbuntuOne.Common\Canonical.UbuntuOne.Common.csproj">
614+ <Project>{11353FF8-8E5A-488E-9CB1-873DADD232B9}</Project>
615+ <Name>Canonical.UbuntuOne.Common</Name>
616+ </ProjectReference>
617+ <ProjectReference Include="..\UbuntuOneClient\UbuntuOneClient.csproj">
618+ <Project>{E41083CC-B99A-4AEC-93CC-F693F6AA6071}</Project>
619+ <Name>UbuntuOneClient</Name>
620+ </ProjectReference>
621+ </ItemGroup>
622+ <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
623+ <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
624+ Other similar extension points exist, see Microsoft.Common.targets.
625+ <Target Name="BeforeBuild">
626+ </Target>
627+ <Target Name="AfterBuild">
628+ </Target>
629+ -->
630+</Project>
631\ No newline at end of file
632
633=== added file 'src/UbuntuOneClient/ApplicationWrapper.cs'
634--- src/UbuntuOneClient/ApplicationWrapper.cs 1970-01-01 00:00:00 +0000
635+++ src/UbuntuOneClient/ApplicationWrapper.cs 2010-07-30 09:47:43 +0000
636@@ -0,0 +1,55 @@
637+using System;
638+/**
639+ * Copyright 2010 Canonical Ltd.
640+ *
641+ * This file is part of UbuntuOne on Windows.
642+ *
643+ * UbuntuOne on Windows is free software: you can redistribute it and/or modify
644+ * it under the terms of the GNU Lesser General Public License version
645+ * as published by the Free Software Foundation.
646+ *
647+ * Ubuntu One on Windows is distributed in the hope that it will be useful,
648+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
649+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
650+ * GNU Lesser General Public License for more details.
651+ *
652+ * You should have received a copy of the GNU Lesser General Public License
653+ * along with UbuntuOne for Windows. If not, see <http://www.gnu.org/licenses/>.
654+ *
655+ * Authors: Manuel de la Peña <manuel.delapena@canonical.com>
656+ */
657+using System.Threading;
658+using System.Windows;
659+using Canonical.UbuntuOne.Client.Notification;
660+using Canonical.UbuntuOne.Common.Validation;
661+
662+namespace UbuntuOneClient
663+{
664+ /// <summary>
665+ /// Helper class that has been created to allow an easy way to test the Program class that starts the application.
666+ /// </summary>
667+ internal class ApplicationWrapper : IApplication
668+ {
669+ private readonly Application _app;
670+
671+ public ApplicationWrapper()
672+ {
673+ _app = new Application();
674+ }
675+
676+ public void Run(INotificationIconView notificationIcon)
677+ {
678+ ValidateArgs.Begin()
679+ .IsOfType(notificationIcon, typeof (Window), "notificationIcon")
680+ .Check();
681+ var window = (Window)notificationIcon;
682+ _app.Run(window);
683+ }
684+
685+ public ShutdownMode ShutdownMode
686+ {
687+ get { return _app.ShutdownMode; }
688+ set { _app.ShutdownMode = value; }
689+ }
690+ }
691+}
692
693=== added file 'src/UbuntuOneClient/IApplication.cs'
694--- src/UbuntuOneClient/IApplication.cs 1970-01-01 00:00:00 +0000
695+++ src/UbuntuOneClient/IApplication.cs 2010-07-30 09:47:43 +0000
696@@ -0,0 +1,41 @@
697+/**
698+ * Copyright 2010 Canonical Ltd.
699+ *
700+ * This file is part of UbuntuOne on Windows.
701+ *
702+ * UbuntuOne on Windows is free software: you can redistribute it and/or modify
703+ * it under the terms of the GNU Lesser General Public License version
704+ * as published by the Free Software Foundation.
705+ *
706+ * Ubuntu One on Windows is distributed in the hope that it will be useful,
707+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
708+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
709+ * GNU Lesser General Public License for more details.
710+ *
711+ * You should have received a copy of the GNU Lesser General Public License
712+ * along with UbuntuOne for Windows. If not, see <http://www.gnu.org/licenses/>.
713+ *
714+ * Authors: Manuel de la Peña <manuel.delapena@canonical.com>
715+ */
716+using System.Windows;
717+using Canonical.UbuntuOne.Client.Notification;
718+
719+namespace UbuntuOneClient
720+{
721+ /// <summary>
722+ /// Helper interface that has been added to make the code more testable in the program class.
723+ /// </summary>
724+ public interface IApplication
725+ {
726+ /// <summary>
727+ /// Runs an application using the passed window as its main window in the thread.
728+ /// </summary>
729+ /// <param name="notificationIcon">The notification icon used by the user to interact with the daemon.</param>
730+ void Run(INotificationIconView notificationIcon);
731+
732+ /// <summary>
733+ /// Gets and sets the shutdown mode to be used in the application.
734+ /// </summary>
735+ ShutdownMode ShutdownMode { get; set; }
736+ }
737+}
738
739=== modified file 'src/UbuntuOneClient/Program.cs'
740--- src/UbuntuOneClient/Program.cs 2010-07-28 07:47:45 +0000
741+++ src/UbuntuOneClient/Program.cs 2010-07-30 09:47:43 +0000
742@@ -18,25 +18,138 @@
743 * Authors: Manuel de la Peña <manuel.delapena@canonical.com>
744 */
745 using System;
746+using System.Threading;
747 using System.Windows;
748-using Canonical.UbuntuOne.Client.Views;
749+using Canonical.UbuntuOne.Client.Notification;
750 using Canonical.UbuntuOne.Common.Container;
751+using Canonical.UbuntuOne.Common.Update;
752 using log4net;
753
754 namespace UbuntuOneClient
755 {
756- class Program
757+ /// <summary>
758+ /// Class that will start the application when needed.
759+ /// </summary>
760+ internal class Program
761 {
762- private static ILog _logger = LogManager.GetLogger(typeof(Program));
763+ private static readonly ILog _logger = LogManager.GetLogger(typeof(Program));
764+ private IUpdater _updater;
765+ private readonly object _updaterLock = new object();
766+ private INotificationIconView _notifyIcon;
767+ private readonly object _notifyIconLock = new object();
768+ private Thread _updatesThread;
769+ #region DI Properties for testability
770+
771+ /// <summary>
772+ /// Allows to get and set the updater to be used, if the updater is not present the class
773+ /// will use the ObjectsContainer to retrieve it. This property has been added to increase the testability
774+ /// of the class.
775+ /// </summary>
776+ internal IUpdater Updater
777+ {
778+ get
779+ {
780+ if(_updater == null)
781+ {
782+ lock(_updaterLock)
783+ {
784+ _updater = ObjectsContainer.GetImplementationOf<IUpdater>();
785+ }
786+ }
787+ return _updater;
788+ }
789+ set { _updater = value; }
790+ }
791+
792+ /// <summary>
793+ /// Allows to get and set the notification icon, if the notification icon is not present the class
794+ /// will use the Objects container to retrieve it. This property has been added to icrease the testability of the
795+ /// class.
796+ /// </summary>
797+ internal INotificationIconView NotifyIcon
798+ {
799+ get
800+ {
801+ if(_notifyIcon == null)
802+ {
803+ lock (_notifyIconLock)
804+ {
805+ _notifyIcon = ObjectsContainer.GetImplementationOf<INotificationIconView>();
806+ }
807+ }
808+ return _notifyIcon;
809+ }
810+ set { _notifyIcon = value; }
811+ }
812+
813+ /// <summary>
814+ /// Allows to get and set the application that will be used to ran the client. This property has been
815+ /// added to increase the testability of the class.
816+ /// </summary>
817+ internal IApplication Application { get; set; }
818+
819+ #endregion
820+
821+ #region Helper methods
822+
823+ /// <summary>
824+ /// Helper method that will check for updates and will ask the user if an update is required.
825+ /// </summary>
826+ private void CheckForUpdates()
827+ {
828+ try
829+ {
830+ if (!Updater.UpdatesArePresent()) return;
831+ _logger.Info("Updates are available.");
832+ Updater.PerformUpdate();
833+ }catch(SelfUpdateException ex)
834+ {
835+ _logger.WarnFormat("Application could not be update {0}", ex);
836+ }
837+ }
838+
839+ #endregion
840+
841+ /// <summary>
842+ /// Starts the application when requested. The code has been refactored to this method to allow
843+ /// unit testing.
844+ /// </summary>
845+ public void StartApplication()
846+ {
847+ _logger.Debug("Starting client application.");
848+ // we explicitly want to stop the application
849+ Application.ShutdownMode = ShutdownMode.OnExplicitShutdown;
850+ // we start the check for updates in another thread so that we do not block the user,
851+ // that way we will not stop the execution of the application while we chec the rss feed.
852+ _updatesThread = new Thread(CheckForUpdates);
853+ _updatesThread.Start();
854+ // we do not worry about looping to allow the other thread to finish, we no that app should take longer
855+ Application.Run(NotifyIcon);
856+ }
857+
858+ /// <summary>
859+ /// Allows to stop the trhad that is checking if updates are avialble.
860+ /// </summary>
861+ public void StopUpdaterThread()
862+ {
863+ if(_updatesThread != null)
864+ {
865+ _updatesThread.Join();
866+ }
867+ else
868+ {
869+ _logger.Warn("Not update thread exists.");
870+ }
871+ }
872+
873
874 [STAThread]
875 static void Main()
876 {
877- _logger.Debug("Starting client application.");
878+ // init the objects container
879 ObjectsContainer.Initialize(new SpringContainer());
880- var notifyIcon = ObjectsContainer.GetImplementationOf<UbuntuOneNotifyIcon>();
881- var app = new Application {ShutdownMode = ShutdownMode.OnExplicitShutdown};
882- app.Run(notifyIcon);
883+ var program = ObjectsContainer.GetImplementationOf<Program>();
884+ program.StartApplication();
885 }
886 }
887 }
888
889=== modified file 'src/UbuntuOneClient/Properties/AssemblyInfo.cs'
890--- src/UbuntuOneClient/Properties/AssemblyInfo.cs 2010-07-27 14:19:43 +0000
891+++ src/UbuntuOneClient/Properties/AssemblyInfo.cs 2010-07-30 09:47:43 +0000
892@@ -53,3 +53,5 @@
893 // [assembly: AssemblyVersion("1.0.*")]
894 [assembly: AssemblyVersion("1.0.0.0")]
895 [assembly: AssemblyFileVersion("1.0.0.0")]
896+// allow the test assembly to access the internals
897+[assembly: InternalsVisibleTo("UbuntuOneClient.Tests")]
898
899=== modified file 'src/UbuntuOneClient/UbuntuOneClient.csproj'
900--- src/UbuntuOneClient/UbuntuOneClient.csproj 2010-07-28 07:47:45 +0000
901+++ src/UbuntuOneClient/UbuntuOneClient.csproj 2010-07-30 09:47:43 +0000
902@@ -62,6 +62,8 @@
903 <Reference Include="PresentationFramework" />
904 </ItemGroup>
905 <ItemGroup>
906+ <Compile Include="ApplicationWrapper.cs" />
907+ <Compile Include="IApplication.cs" />
908 <Compile Include="Program.cs" />
909 <Compile Include="Properties\AssemblyInfo.cs">
910 <SubType>Code</SubType>
911@@ -96,6 +98,10 @@
912 <Project>{1F0E3DAF-F22F-4B0C-8039-118B082DA237}</Project>
913 <Name>Canonical.UbuntuOne.Client.Views</Name>
914 </ProjectReference>
915+ <ProjectReference Include="..\Canonical.UbuntuOne.Client\Canonical.UbuntuOne.Client.csproj">
916+ <Project>{7467483A-D6D5-4362-8DF4-57A7254EB569}</Project>
917+ <Name>Canonical.UbuntuOne.Client</Name>
918+ </ProjectReference>
919 <ProjectReference Include="..\Canonical.UbuntuOne.Common\Canonical.UbuntuOne.Common.csproj">
920 <Project>{11353FF8-8E5A-488E-9CB1-873DADD232B9}</Project>
921 <Name>Canonical.UbuntuOne.Common</Name>
922
923=== modified file 'src/UbuntuOneClient/objects.xml'
924--- src/UbuntuOneClient/objects.xml 2010-07-28 07:47:45 +0000
925+++ src/UbuntuOneClient/objects.xml 2010-07-30 09:47:43 +0000
926@@ -1,6 +1,22 @@
927 <?xml version="1.0" encoding="utf-8" ?>
928 <objects xmlns="http://www.springframework.net">
929 <!-- Define window that will be used as the start point of the app -->
930+ <object id="Updater"
931+ type="Canonical.UbuntuOne.Common.Update.Updater, Canonical.UbuntuOne.Common" >
932+ <property name="RSSFeed"
933+ value="http://path/to/rss.feed"/>
934+ </object>
935+
936 <object id="UbuntuOneNotifyIcon"
937 type="Canonical.UbuntuOne.Client.Views.UbuntuOneNotifyIcon, Canonical.UbuntuOne.Client.Views" />
938+
939+ <object id="Application"
940+ type="UbuntuOneClient.ApplicationWrapper, UbuntuOneClient" />
941+
942+ <object id="Program"
943+ type="UbuntuOneClient.Program, UbuntuOneClient"
944+ autowire="autodetect" >
945+ <property name="Application"
946+ ref="Application" />
947+ </object>
948 </objects>
949\ No newline at end of file

Subscribers

People subscribed via source and target branches

to all changes: