From 1dfdccb8118aeaa3cd844ac8de2a672c93312166 Mon Sep 17 00:00:00 2001 From: mokhan Date: Sat, 21 Feb 2009 21:44:27 +0000 Subject: git-svn-id: http://svn.xp-dev.com/svn/mokhan-sait@2 da190166-9cfc-4ee1-ae03-434a172be219 --- slips/src/app/Marina.Web.UI/AvailableSlips.aspx | 37 +++ slips/src/app/Marina.Web.UI/AvailableSlips.aspx.cs | 21 ++ .../Marina.Web.UI/AvailableSlips.aspx.designer.cs | 16 + slips/src/app/Marina.Web.UI/ContactUs.aspx | 23 ++ slips/src/app/Marina.Web.UI/ContactUs.aspx.cs | 8 + .../app/Marina.Web.UI/ContactUs.aspx.designer.cs | 16 + slips/src/app/Marina.Web.UI/CurrentLeases.aspx | 28 ++ slips/src/app/Marina.Web.UI/CurrentLeases.aspx.cs | 19 ++ .../Marina.Web.UI/CurrentLeases.aspx.designer.cs | 25 ++ slips/src/app/Marina.Web.UI/Default.aspx | 19 ++ slips/src/app/Marina.Web.UI/Default.aspx.cs | 8 + .../src/app/Marina.Web.UI/Default.aspx.designer.cs | 16 + slips/src/app/Marina.Web.UI/DockView.aspx | 60 ++++ slips/src/app/Marina.Web.UI/DockView.aspx.cs | 26 ++ .../app/Marina.Web.UI/DockView.aspx.designer.cs | 25 ++ slips/src/app/Marina.Web.UI/Global.asax | 1 + slips/src/app/Marina.Web.UI/LeaseSlip.aspx | 46 +++ slips/src/app/Marina.Web.UI/LeaseSlip.aspx.cs | 26 ++ .../app/Marina.Web.UI/LeaseSlip.aspx.designer.cs | 25 ++ slips/src/app/Marina.Web.UI/Login.aspx | 36 +++ slips/src/app/Marina.Web.UI/Login.aspx.cs | 22 ++ slips/src/app/Marina.Web.UI/Login.aspx.designer.cs | 34 +++ slips/src/app/Marina.Web.UI/Marina.Web.UI.csproj | 215 ++++++++++++++ slips/src/app/Marina.Web.UI/RegisterBoat.aspx | 48 +++ slips/src/app/Marina.Web.UI/RegisterBoat.aspx.cs | 20 ++ .../Marina.Web.UI/RegisterBoat.aspx.designer.cs | 34 +++ slips/src/app/Marina.Web.UI/Registration.aspx | 48 +++ slips/src/app/Marina.Web.UI/Registration.aspx.cs | 44 +++ .../Marina.Web.UI/Registration.aspx.designer.cs | 34 +++ slips/src/app/Marina.Web.UI/Site.Master | 89 ++++++ slips/src/app/Marina.Web.UI/Site.Master.cs | 8 + .../src/app/Marina.Web.UI/Site.Master.designer.cs | 43 +++ .../Marina.Web.UI/UpdateCustomerRegistration.aspx | 52 ++++ .../UpdateCustomerRegistration.aspx.cs | 27 ++ .../UpdateCustomerRegistration.aspx.designer.cs | 34 +++ .../src/app/Marina.Web.UI/ViewRegisteredBoats.aspx | 34 +++ .../app/Marina.Web.UI/ViewRegisteredBoats.aspx.cs | 19 ++ .../ViewRegisteredBoats.aspx.designer.cs | 25 ++ slips/src/app/Marina.Web.UI/Web.config | 95 ++++++ slips/src/app/Marina.Web.UI/WebServicesAPI.aspx | 15 + slips/src/app/Marina.Web.UI/WebServicesAPI.aspx.cs | 23 ++ .../Marina.Web.UI/WebServicesAPI.aspx.designer.cs | 16 + slips/src/app/Marina.Web.UI/images/back.png | Bin 0 -> 224 bytes slips/src/app/Marina.Web.UI/images/graphic.jpg | Bin 0 -> 2002 bytes slips/src/app/Marina.Web.UI/images/link.png | Bin 0 -> 186 bytes slips/src/app/Marina.Web.UI/images/logo.jpg | Bin 0 -> 16985 bytes slips/src/app/Marina.Web.UI/images/menu.png | Bin 0 -> 165 bytes slips/src/app/Marina.Web.UI/images/menu_hover.png | Bin 0 -> 166 bytes slips/src/app/Marina.Web.UI/images/sbi_header.png | Bin 0 -> 201 bytes slips/src/app/Marina.Web.UI/style/colour.css | 85 ++++++ slips/src/app/Marina.Web.UI/style/style.css | 274 ++++++++++++++++++ slips/src/app/Marina.Web.UI/windsor.config.xml | 116 ++++++++ .../Marina/DataAccess/Builders/DatabaseDelete.cs | 31 ++ .../Marina/DataAccess/Builders/DatabaseInsert.cs | 50 ++++ .../Marina/DataAccess/Builders/DatabaseSelect.cs | 101 +++++++ .../Marina/DataAccess/Builders/DatabaseUpdate.cs | 52 ++++ .../DataAccess/Builders/IDeleteQueryBuilder.cs | 3 + .../DataAccess/Builders/IInsertQueryBuilder.cs | 5 + slips/src/app/Marina/DataAccess/Builders/IJoin.cs | 6 + slips/src/app/Marina/DataAccess/Builders/IQuery.cs | 7 + .../Marina/DataAccess/Builders/IQueryBuilder.cs | 9 + .../DataAccess/Builders/ISelectQueryBuilder.cs | 11 + .../DataAccess/Builders/IUpdateQueryBuilder.cs | 5 + slips/src/app/Marina/DataAccess/Builders/Query.cs | 22 ++ .../src/app/Marina/DataAccess/Builders/SqlQuery.cs | 18 ++ .../app/Marina/DataAccess/Builders/WhereClause.cs | 27 ++ .../DataAccess/DataMappers/BoatDataMapper.cs | 74 +++++ .../DataAccess/DataMappers/CustomerDataMapper.cs | 82 ++++++ .../DataAccess/DataMappers/DockDataMapper.cs | 54 ++++ .../DataAccess/DataMappers/IBoatDataMapper.cs | 12 + .../DataAccess/DataMappers/ICustomerDataMapper.cs | 11 + .../Marina/DataAccess/DataMappers/IDataMapper.cs | 5 + .../DataAccess/DataMappers/IDockDataMapper.cs | 6 + .../DataAccess/DataMappers/ILeaseDataMapper.cs | 14 + .../DataMappers/IRegistrationDataMapper.cs | 11 + .../DataAccess/DataMappers/ISlipDataMapper.cs | 9 + .../DataAccess/DataMappers/LeaseDataMapper.cs | 87 ++++++ .../DataMappers/RegistrationDataMapper.cs | 88 ++++++ .../DataAccess/DataMappers/SlipDataMapper.cs | 97 +++++++ slips/src/app/Marina/DataAccess/DatabaseColumn.cs | 23 ++ slips/src/app/Marina/DataAccess/DatabaseCommand.cs | 23 ++ .../Marina/DataAccess/DatabaseCommandParameter.cs | 19 ++ .../app/Marina/DataAccess/DatabaseConfiguration.cs | 22 ++ .../app/Marina/DataAccess/DatabaseConnection.cs | 38 +++ .../Marina/DataAccess/DatabaseConnectionFactory.cs | 7 + slips/src/app/Marina/DataAccess/DatabaseGateway.cs | 60 ++++ .../Marina/DataAccess/DatabaseProviderFactory.cs | 10 + slips/src/app/Marina/DataAccess/DatabaseRow.cs | 24 ++ .../app/Marina/DataAccess/DatabaseTransaction.cs | 19 ++ .../ObjectAlreadyAddedToIdentityMapException.cs | 9 + .../src/app/Marina/DataAccess/IDatabaseCommand.cs | 9 + .../Marina/DataAccess/IDatabaseConfiguration.cs | 7 + .../app/Marina/DataAccess/IDatabaseConnection.cs | 10 + .../DataAccess/IDatabaseConnectionFactory.cs | 5 + .../src/app/Marina/DataAccess/IDatabaseGateway.cs | 19 ++ .../Marina/DataAccess/IDatabaseProviderFactory.cs | 7 + slips/src/app/Marina/DataAccess/IDatabaseRow.cs | 5 + .../app/Marina/DataAccess/IDatabaseTransaction.cs | 7 + slips/src/app/Marina/DataAccess/IIdentityMap.cs | 9 + slips/src/app/Marina/DataAccess/IdentityMap.cs | 42 +++ .../DataAccess/Repositories/CustomerRepository.cs | 51 ++++ .../DataAccess/Repositories/DockRepository.cs | 20 ++ .../DataAccess/Repositories/SlipsRepository.cs | 58 ++++ .../DataAccess/Schemas/AuthorizationTable.cs | 9 + .../src/app/Marina/DataAccess/Schemas/BoatTable.cs | 11 + .../app/Marina/DataAccess/Schemas/CustomerTable.cs | 10 + .../src/app/Marina/DataAccess/Schemas/DockTable.cs | 10 + .../app/Marina/DataAccess/Schemas/LeaseTable.cs | 11 + .../src/app/Marina/DataAccess/Schemas/LeaseType.cs | 8 + .../app/Marina/DataAccess/Schemas/LocationTable.cs | 7 + .../src/app/Marina/DataAccess/Schemas/SlipTable.cs | 9 + slips/src/app/Marina/Domain/Boat.cs | 72 +++++ slips/src/app/Marina/Domain/BrokenRule.cs | 15 + slips/src/app/Marina/Domain/Customer.cs | 76 +++++ .../src/app/Marina/Domain/CustomerRegistration.cs | 151 ++++++++++ slips/src/app/Marina/Domain/DateRange.cs | 22 ++ slips/src/app/Marina/Domain/Dock.cs | 33 +++ slips/src/app/Marina/Domain/DomainObject.cs | 19 ++ .../Exceptions/SlipIsAlreadyLeasedException.cs | 5 + slips/src/app/Marina/Domain/Interfaces/IBoat.cs | 13 + .../app/Marina/Domain/Interfaces/IBrokenRule.cs | 5 + .../app/Marina/Domain/Interfaces/IBusinessRule.cs | 9 + .../src/app/Marina/Domain/Interfaces/ICustomer.cs | 27 ++ .../src/app/Marina/Domain/Interfaces/IDateRange.cs | 9 + slips/src/app/Marina/Domain/Interfaces/IDock.cs | 11 + .../app/Marina/Domain/Interfaces/IDomainObject.cs | 7 + .../app/Marina/Domain/Interfaces/ILeaseDuration.cs | 10 + .../src/app/Marina/Domain/Interfaces/ILeaseType.cs | 7 + .../src/app/Marina/Domain/Interfaces/ILocation.cs | 5 + slips/src/app/Marina/Domain/Interfaces/IRange.cs | 11 + .../app/Marina/Domain/Interfaces/IRegistration.cs | 22 ++ slips/src/app/Marina/Domain/Interfaces/ISlip.cs | 15 + .../src/app/Marina/Domain/Interfaces/ISlipLease.cs | 13 + slips/src/app/Marina/Domain/Interfaces/IUtility.cs | 5 + slips/src/app/Marina/Domain/LeaseDurations.cs | 62 ++++ slips/src/app/Marina/Domain/Location.cs | 15 + slips/src/app/Marina/Domain/Range.cs | 32 ++ .../Domain/Repositories/ICustomerRepository.cs | 13 + .../Marina/Domain/Repositories/IDockRepository.cs | 7 + .../Marina/Domain/Repositories/ISlipsRepository.cs | 12 + slips/src/app/Marina/Domain/Slip.cs | 46 +++ slips/src/app/Marina/Domain/SlipLease.cs | 37 +++ slips/src/app/Marina/Domain/UnknownCustomer.cs | 39 +++ slips/src/app/Marina/Domain/Utilities.cs | 91 ++++++ .../src/app/Marina/Infrastructure/BlankCommand.cs | 5 + .../Configuration/ConfigurationItem.cs | 13 + .../Configuration/ConfigurationItems.cs | 15 + .../Container/Custom/CustomDependencyContainer.cs | 21 ++ .../Container/IDependencyContainer.cs | 5 + .../Container/InterfaceResolutionException.cs | 11 + .../app/Marina/Infrastructure/Container/Resolve.cs | 21 ++ .../Windsor/WindsorDependencyContainer.cs | 16 + .../app/Marina/Infrastructure/EnumerableMapper.cs | 17 ++ slips/src/app/Marina/Infrastructure/ICommand.cs | 5 + slips/src/app/Marina/Infrastructure/IFactory.cs | 5 + slips/src/app/Marina/Infrastructure/IMapper.cs | 5 + .../app/Marina/Infrastructure/IRichEnumerable.cs | 7 + slips/src/app/Marina/Infrastructure/IRichList.cs | 91 ++++++ .../app/Marina/Infrastructure/ISpecification.cs | 5 + .../Marina/Infrastructure/ISpecificationBuilder.cs | 5 + .../src/app/Marina/Infrastructure/ITransformer.cs | 5 + .../Infrastructure/IValueReturningVisitor.cs | 5 + slips/src/app/Marina/Infrastructure/IVisitor.cs | 5 + slips/src/app/Marina/Infrastructure/ListFactory.cs | 20 ++ .../Infrastructure/Logging/Interfaces/ILog.cs | 7 + .../Logging/Interfaces/ILogFactory.cs | 7 + .../Infrastructure/Logging/Interfaces/Log.cs | 14 + .../Log4Net/ILog4NetInitializationCommand.cs | 8 + .../Log4Net/Log4NetInitializationCommand.cs | 19 ++ .../Infrastructure/Logging/Log4Net/Log4NetLog.cs | 23 ++ .../Logging/Log4Net/Log4NetLogFactory.cs | 30 ++ .../Logging/TextWriterLogging/TextWriterLog.cs | 24 ++ .../TextWriterLogging/TextWriterLogFactory.cs | 10 + .../app/Marina/Infrastructure/RichEnumerable.cs | 28 ++ slips/src/app/Marina/Infrastructure/RichList.cs | 45 +++ .../Marina/Infrastructure/SpecificationBuilder.cs | 44 +++ slips/src/app/Marina/Infrastructure/Transform.cs | 7 + slips/src/app/Marina/Infrastructure/Transformer.cs | 22 ++ slips/src/app/Marina/Marina.csproj | 322 +++++++++++++++++++++ .../Marina/Presentation/DTO/BoatRegistrationDTO.cs | 41 +++ .../DTO/CustomerRegistrationDisplayDTO.cs | 91 ++++++ .../app/Marina/Presentation/DTO/DisplayLeaseDTO.cs | 28 ++ .../Presentation/DTO/DisplayResponseLineDTO.cs | 36 +++ .../Presentation/DTO/DisplayResponseLines.cs | 24 ++ .../app/Marina/Presentation/DTO/DockDisplayDTO.cs | 36 +++ .../Marina/Presentation/DTO/LoginCredentialsDTO.cs | 24 ++ .../Marina/Presentation/DTO/RegisterCustomerDTO.cs | 47 +++ .../app/Marina/Presentation/DTO/SlipDisplayDTO.cs | 48 +++ .../Presentation/DTO/SubmitLeaseRequestDTO.cs | 60 ++++ .../DTO/UpdateCustomerRegistrationDTO.cs | 53 ++++ .../CustomerRegistrationPresentationMapper.cs | 17 ++ .../ICustomerRegistrationPresentationMapper.cs | 8 + .../ILeaseRequestDtoFromHttpRequestMapper.cs | 7 + .../Mappers/ILoginCredentialsMapper.cs | 7 + .../Mappers/INewBoatRegistrationMapper.cs | 7 + .../IUpdateRegistrationPresentationMapper.cs | 7 + .../LeaseRequestDtoFromHttpRequestMapper.cs | 14 + .../Presentation/Mappers/LoginCredentialsMapper.cs | 13 + .../Mappers/NewBoatRegistrationMapper.cs | 16 + .../UpdateRegistrationPresentationMapper.cs | 18 ++ slips/src/app/Marina/Presentation/PayLoadKeys.cs | 12 + slips/src/app/Marina/Presentation/PayloadKey.cs | 48 +++ .../Presentation/PayloadKeyNotFoundException.cs | 7 + .../Presenters/AvailableSlipsPresenter.cs | 25 ++ .../Presenters/CurrentLeasesPresenter.cs | 25 ++ .../Presenters/CustomerRegistrationPresenter.cs | 30 ++ .../Presentation/Presenters/DockPresenter.cs | 31 ++ .../Presenters/IAvailableSlipsPresenter.cs | 5 + .../Presenters/ICurrentLeasesPresenter.cs | 5 + .../Presenters/ICustomerRegistrationPresenter.cs | 5 + .../Presentation/Presenters/IDockPresenter.cs | 5 + .../Presentation/Presenters/ILeaseSlipPresenter.cs | 7 + .../Presentation/Presenters/ILoginPresenter.cs | 5 + .../Presenters/IRegisterBoatPresenter.cs | 5 + .../IUpdateCustomerRegistrationPresenter.cs | 7 + .../Presenters/IViewRegisteredBoatsPresenter.cs | 5 + .../Presentation/Presenters/LeaseSlipPresenter.cs | 41 +++ .../Presentation/Presenters/LoginPresenter.cs | 34 +++ .../Presenters/RegisterBoatPresenter.cs | 33 +++ .../UpdateCustomerRegistrationPresenter.cs | 44 +++ .../Presenters/ViewRegisteredBoatsPresenter.cs | 25 ++ .../Presentation/Views/IAvailableSlipsView.cs | 8 + .../Presentation/Views/ICurrentLeasesView.cs | 8 + .../Views/ICustomerRegistrationView.cs | 20 ++ .../src/app/Marina/Presentation/Views/IDockView.cs | 9 + .../Marina/Presentation/Views/ILeaseSlipView.cs | 9 + .../app/Marina/Presentation/Views/ILoginView.cs | 7 + .../Marina/Presentation/Views/IRegisterBoatView.cs | 8 + .../Presentation/Views/IRegisteredBoatsView.cs | 8 + .../Presentation/Views/IUpdateRegistrationView.cs | 9 + slips/src/app/Marina/Properties/AssemblyInfo.cs | 36 +++ .../src/app/Marina/Task/ApplicationStartupTask.cs | 14 + slips/src/app/Marina/Task/AuthenticationTask.cs | 41 +++ slips/src/app/Marina/Task/CatalogTasks.cs | 52 ++++ .../src/app/Marina/Task/IApplicationStartupTask.cs | 5 + slips/src/app/Marina/Task/IAuthenticationTask.cs | 7 + slips/src/app/Marina/Task/ICatalogTasks.cs | 14 + slips/src/app/Marina/Task/ILeaseTasks.cs | 10 + slips/src/app/Marina/Task/IRegistrationTasks.cs | 16 + slips/src/app/Marina/Task/LeaseTasks.cs | 39 +++ .../Task/Mappers/BrokenRulesToDisplayItemMapper.cs | 13 + .../Marina/Task/Mappers/DockToDisplayDTOMapper.cs | 16 + .../Mappers/IBrokenRulesToDisplayItemMapper.cs | 9 + .../Marina/Task/Mappers/IDockToDisplayDTOMapper.cs | 7 + .../app/Marina/Task/Mappers/ILeaseToDtoMapper.cs | 7 + .../Task/Mappers/ISlipsToDisplayDTOMapper.cs | 7 + .../app/Marina/Task/Mappers/LeaseToDtoMapper.cs | 12 + .../Marina/Task/Mappers/SlipsToDisplayDTOMapper.cs | 16 + slips/src/app/Marina/Task/RegistrationTasks.cs | 92 ++++++ .../src/app/Marina/Web/AuthenticationHttpModule.cs | 28 ++ .../Marina/Web/Commands/AvailableSlipsCommand.cs | 23 ++ slips/src/app/Marina/Web/Commands/CommandNames.cs | 5 + .../src/app/Marina/Web/Commands/RedirectCommand.cs | 11 + slips/src/app/Marina/Web/CurrentHttpContext.cs | 135 +++++++++ slips/src/app/Marina/Web/CurrentHttpRequest.cs | 20 ++ slips/src/app/Marina/Web/FrontController.cs | 21 ++ slips/src/app/Marina/Web/GlobalApplication.cs | 17 ++ .../Marina/Web/Handlers/AvailableSlipsHandler.cs | 7 + slips/src/app/Marina/Web/Handlers/Dispatcher.cs | 24 ++ .../app/Marina/Web/Handlers/IRegisteredHandlers.cs | 8 + .../src/app/Marina/Web/Handlers/IRequestHandler.cs | 6 + .../app/Marina/Web/Handlers/RegisteredHandlers.cs | 9 + .../src/app/Marina/Web/Handlers/RequestHandler.cs | 26 ++ .../Web/Handlers/RequestHandlerSpecification.cs | 16 + slips/src/app/Marina/Web/Http/HttpGateway.cs | 71 +++++ slips/src/app/Marina/Web/Http/IHttpGateway.cs | 16 + slips/src/app/Marina/Web/IHttpContext.cs | 69 +++++ slips/src/app/Marina/Web/IHttpRequest.cs | 7 + slips/src/app/Marina/Web/Redirect.cs | 10 + .../Web/Services/AuthenticationServices.asmx | 1 + .../Web/Services/AuthenticationWebServices.cs | 21 ++ .../app/Marina/Web/Services/CatalogServices.asmx | 1 + .../app/Marina/Web/Services/CatalogWebServices.cs | 35 +++ .../src/app/Marina/Web/Services/LeaseServices.asmx | 1 + .../app/Marina/Web/Services/LeaseWebServices.cs | 26 ++ .../Marina/Web/Services/RegistrationServices.asmx | 1 + .../Marina/Web/Services/RegistrationWebServices.cs | 38 +++ .../Marina/Web/UnhandledExceptionsHttpModule.cs | 19 ++ slips/src/app/Marina/Web/Views/IView.cs | 7 + .../src/app/Marina/Web/Views/IViewLuggageTicket.cs | 3 + .../Marina/Web/Views/IViewLuggageTransporter.cs | 7 + slips/src/app/Marina/Web/Views/IWebView.cs | 5 + .../Web/Views/Pages/AvailableSlipsWebView.cs | 16 + .../Web/Views/Pages/IAvailableSlipsWebView.cs | 6 + slips/src/app/Marina/Web/Views/View.cs | 28 ++ slips/src/app/Marina/Web/Views/ViewLuggage.cs | 11 + .../src/app/Marina/Web/Views/ViewLuggageTickets.cs | 14 + .../app/Marina/Web/Views/ViewLuggageTransporter.cs | 32 ++ slips/src/app/Marina/Web/Views/WebView.cs | 27 ++ slips/src/app/Marina/Web/Views/WebViews.cs | 18 ++ .../DataAccess/Mappers/BoatDataMapperTest.cs | 78 +++++ .../DataAccess/Mappers/CustomerDataMapperTest.cs | 25 ++ .../DataAccess/Mappers/LeaseDataMapperTest.cs | 44 +++ .../Mappers/RegistrationDataMapperTest.cs | 70 +++++ .../DataAccess/Repositories/DockRepositoryTest.cs | 24 ++ .../DataAccess/Repositories/SlipRepositoryTest.cs | 32 ++ .../Integration/DataAccess/Utility/BoatMother.cs | 19 ++ .../DataAccess/Utility/CustomerMother.cs | 34 +++ .../Integration/DataAccess/Utility/LeaseMother.cs | 21 ++ .../Integration/DataAccess/Utility/SlipMother.cs | 18 ++ .../Integration/Task/CatalogTasksTest.cs | 19 ++ slips/src/test/Marina.Test/Marina.Test.csproj | 136 +++++++++ .../test/Marina.Test/Properties/AssemblyInfo.cs | 36 +++ .../Unit/DataAccess/DatabaseCommandTest.cs | 48 +++ .../Unit/DataAccess/DatabaseConfigurationTest.cs | 33 +++ .../Unit/DataAccess/DatabaseConnectionTest.cs | 167 +++++++++++ .../Unit/DataAccess/DatabaseGatewayTest.cs | 91 ++++++ .../DataAccess/Mappers/CustomerDataMapperTest.cs | 86 ++++++ .../Repositories/CustomerRepositoryTest.cs | 142 +++++++++ .../DataAccess/Repositories/DockRepositoryTest.cs | 38 +++ .../DataAccess/Repositories/IdentityMapTest.cs | 71 +++++ .../DataAccess/Repositories/SlipRepositoryTest.cs | 50 ++++ .../Unit/Domain/CustomerRegistrationTest.cs | 50 ++++ .../test/Marina.Test/Unit/Domain/CustomerTest.cs | 118 ++++++++ slips/src/test/Marina.Test/Unit/Domain/DockTest.cs | 24 ++ .../Marina.Test/Unit/Domain/LeaseDurationTest.cs | 45 +++ slips/src/test/Marina.Test/Unit/Domain/SlipTest.cs | 78 +++++ .../test/Marina.Test/Unit/Domain/UtilitiesTest.cs | 36 +++ .../Infrastructure/Logging/Interfaces/LogTest.cs | 36 +++ .../TextWriterLogging/TextWriterLogFactoryTest.cs | 19 ++ .../Logging/TextWriterLogging/TextWriterLogTest.cs | 26 ++ .../Unit/Infrastructure/TransformTest.cs | 37 +++ .../Presentation/AvailableSlipsPresenterTest.cs | 51 ++++ .../Presentation/CurrentLeasesPresenterTest.cs | 63 ++++ .../CustomerRegistrationPresenterTest.cs | 69 +++++ .../Unit/Presentation/DockPresenterTest.cs | 90 ++++++ .../Unit/Presentation/LeaseSlipPresenterTest.cs | 100 +++++++ .../Unit/Presentation/LoginPresenterTest.cs | 62 ++++ .../CustomerRegistrationPresentationMapperTest.cs | 52 ++++ .../Mappers/LoginCredentialsMapperTest.cs | 35 +++ .../UpdateRegistrationPresentationMapperTest.cs | 57 ++++ .../Unit/Presentation/PayloadKeyTest.cs | 45 +++ .../Unit/Presentation/RegisterBoatPresenterTest.cs | 67 +++++ .../UpdateRegistrationPresenterTest.cs | 92 ++++++ .../ViewRegisteredBoatsPresenterTest.cs | 62 ++++ .../test/Marina.Test/Unit/Task/CatalogTasksTest.cs | 106 +++++++ .../test/Marina.Test/Unit/Task/LeaseTasksTest.cs | 181 ++++++++++++ .../Marina.Test/Unit/Task/RegistrationTasksTest.cs | 217 ++++++++++++++ .../Unit/Web/Commands/AvailableSlipsCommandTest.cs | 56 ++++ .../Handlers/RequestHandlerSpecificationTest.cs | 53 ++++ .../Unit/Web/Handlers/RequestHandlerTest.cs | 49 ++++ .../Web/Views/Pages/AvailableSlipsWebViewTest.cs | 49 ++++ .../test/Marina.Test/Unit/Web/Views/ViewTest.cs | 48 +++ slips/src/test/Marina.Test/Utility/ObjectMother.cs | 69 +++++ .../Utility/RunInRealContainerAttribute.cs | 14 + .../Utility/RunInRealContainerRunInvoker.cs | 18 ++ 346 files changed, 11025 insertions(+) create mode 100644 slips/src/app/Marina.Web.UI/AvailableSlips.aspx create mode 100644 slips/src/app/Marina.Web.UI/AvailableSlips.aspx.cs create mode 100644 slips/src/app/Marina.Web.UI/AvailableSlips.aspx.designer.cs create mode 100644 slips/src/app/Marina.Web.UI/ContactUs.aspx create mode 100644 slips/src/app/Marina.Web.UI/ContactUs.aspx.cs create mode 100644 slips/src/app/Marina.Web.UI/ContactUs.aspx.designer.cs create mode 100644 slips/src/app/Marina.Web.UI/CurrentLeases.aspx create mode 100644 slips/src/app/Marina.Web.UI/CurrentLeases.aspx.cs create mode 100644 slips/src/app/Marina.Web.UI/CurrentLeases.aspx.designer.cs create mode 100644 slips/src/app/Marina.Web.UI/Default.aspx create mode 100644 slips/src/app/Marina.Web.UI/Default.aspx.cs create mode 100644 slips/src/app/Marina.Web.UI/Default.aspx.designer.cs create mode 100644 slips/src/app/Marina.Web.UI/DockView.aspx create mode 100644 slips/src/app/Marina.Web.UI/DockView.aspx.cs create mode 100644 slips/src/app/Marina.Web.UI/DockView.aspx.designer.cs create mode 100644 slips/src/app/Marina.Web.UI/Global.asax create mode 100644 slips/src/app/Marina.Web.UI/LeaseSlip.aspx create mode 100644 slips/src/app/Marina.Web.UI/LeaseSlip.aspx.cs create mode 100644 slips/src/app/Marina.Web.UI/LeaseSlip.aspx.designer.cs create mode 100644 slips/src/app/Marina.Web.UI/Login.aspx create mode 100644 slips/src/app/Marina.Web.UI/Login.aspx.cs create mode 100644 slips/src/app/Marina.Web.UI/Login.aspx.designer.cs create mode 100644 slips/src/app/Marina.Web.UI/Marina.Web.UI.csproj create mode 100644 slips/src/app/Marina.Web.UI/RegisterBoat.aspx create mode 100644 slips/src/app/Marina.Web.UI/RegisterBoat.aspx.cs create mode 100644 slips/src/app/Marina.Web.UI/RegisterBoat.aspx.designer.cs create mode 100644 slips/src/app/Marina.Web.UI/Registration.aspx create mode 100644 slips/src/app/Marina.Web.UI/Registration.aspx.cs create mode 100644 slips/src/app/Marina.Web.UI/Registration.aspx.designer.cs create mode 100644 slips/src/app/Marina.Web.UI/Site.Master create mode 100644 slips/src/app/Marina.Web.UI/Site.Master.cs create mode 100644 slips/src/app/Marina.Web.UI/Site.Master.designer.cs create mode 100644 slips/src/app/Marina.Web.UI/UpdateCustomerRegistration.aspx create mode 100644 slips/src/app/Marina.Web.UI/UpdateCustomerRegistration.aspx.cs create mode 100644 slips/src/app/Marina.Web.UI/UpdateCustomerRegistration.aspx.designer.cs create mode 100644 slips/src/app/Marina.Web.UI/ViewRegisteredBoats.aspx create mode 100644 slips/src/app/Marina.Web.UI/ViewRegisteredBoats.aspx.cs create mode 100644 slips/src/app/Marina.Web.UI/ViewRegisteredBoats.aspx.designer.cs create mode 100644 slips/src/app/Marina.Web.UI/Web.config create mode 100644 slips/src/app/Marina.Web.UI/WebServicesAPI.aspx create mode 100644 slips/src/app/Marina.Web.UI/WebServicesAPI.aspx.cs create mode 100644 slips/src/app/Marina.Web.UI/WebServicesAPI.aspx.designer.cs create mode 100644 slips/src/app/Marina.Web.UI/images/back.png create mode 100644 slips/src/app/Marina.Web.UI/images/graphic.jpg create mode 100644 slips/src/app/Marina.Web.UI/images/link.png create mode 100644 slips/src/app/Marina.Web.UI/images/logo.jpg create mode 100644 slips/src/app/Marina.Web.UI/images/menu.png create mode 100644 slips/src/app/Marina.Web.UI/images/menu_hover.png create mode 100644 slips/src/app/Marina.Web.UI/images/sbi_header.png create mode 100644 slips/src/app/Marina.Web.UI/style/colour.css create mode 100644 slips/src/app/Marina.Web.UI/style/style.css create mode 100644 slips/src/app/Marina.Web.UI/windsor.config.xml create mode 100644 slips/src/app/Marina/DataAccess/Builders/DatabaseDelete.cs create mode 100644 slips/src/app/Marina/DataAccess/Builders/DatabaseInsert.cs create mode 100644 slips/src/app/Marina/DataAccess/Builders/DatabaseSelect.cs create mode 100644 slips/src/app/Marina/DataAccess/Builders/DatabaseUpdate.cs create mode 100644 slips/src/app/Marina/DataAccess/Builders/IDeleteQueryBuilder.cs create mode 100644 slips/src/app/Marina/DataAccess/Builders/IInsertQueryBuilder.cs create mode 100644 slips/src/app/Marina/DataAccess/Builders/IJoin.cs create mode 100644 slips/src/app/Marina/DataAccess/Builders/IQuery.cs create mode 100644 slips/src/app/Marina/DataAccess/Builders/IQueryBuilder.cs create mode 100644 slips/src/app/Marina/DataAccess/Builders/ISelectQueryBuilder.cs create mode 100644 slips/src/app/Marina/DataAccess/Builders/IUpdateQueryBuilder.cs create mode 100644 slips/src/app/Marina/DataAccess/Builders/Query.cs create mode 100644 slips/src/app/Marina/DataAccess/Builders/SqlQuery.cs create mode 100644 slips/src/app/Marina/DataAccess/Builders/WhereClause.cs create mode 100644 slips/src/app/Marina/DataAccess/DataMappers/BoatDataMapper.cs create mode 100644 slips/src/app/Marina/DataAccess/DataMappers/CustomerDataMapper.cs create mode 100644 slips/src/app/Marina/DataAccess/DataMappers/DockDataMapper.cs create mode 100644 slips/src/app/Marina/DataAccess/DataMappers/IBoatDataMapper.cs create mode 100644 slips/src/app/Marina/DataAccess/DataMappers/ICustomerDataMapper.cs create mode 100644 slips/src/app/Marina/DataAccess/DataMappers/IDataMapper.cs create mode 100644 slips/src/app/Marina/DataAccess/DataMappers/IDockDataMapper.cs create mode 100644 slips/src/app/Marina/DataAccess/DataMappers/ILeaseDataMapper.cs create mode 100644 slips/src/app/Marina/DataAccess/DataMappers/IRegistrationDataMapper.cs create mode 100644 slips/src/app/Marina/DataAccess/DataMappers/ISlipDataMapper.cs create mode 100644 slips/src/app/Marina/DataAccess/DataMappers/LeaseDataMapper.cs create mode 100644 slips/src/app/Marina/DataAccess/DataMappers/RegistrationDataMapper.cs create mode 100644 slips/src/app/Marina/DataAccess/DataMappers/SlipDataMapper.cs create mode 100644 slips/src/app/Marina/DataAccess/DatabaseColumn.cs create mode 100644 slips/src/app/Marina/DataAccess/DatabaseCommand.cs create mode 100644 slips/src/app/Marina/DataAccess/DatabaseCommandParameter.cs create mode 100644 slips/src/app/Marina/DataAccess/DatabaseConfiguration.cs create mode 100644 slips/src/app/Marina/DataAccess/DatabaseConnection.cs create mode 100644 slips/src/app/Marina/DataAccess/DatabaseConnectionFactory.cs create mode 100644 slips/src/app/Marina/DataAccess/DatabaseGateway.cs create mode 100644 slips/src/app/Marina/DataAccess/DatabaseProviderFactory.cs create mode 100644 slips/src/app/Marina/DataAccess/DatabaseRow.cs create mode 100644 slips/src/app/Marina/DataAccess/DatabaseTransaction.cs create mode 100644 slips/src/app/Marina/DataAccess/Exceptions/ObjectAlreadyAddedToIdentityMapException.cs create mode 100644 slips/src/app/Marina/DataAccess/IDatabaseCommand.cs create mode 100644 slips/src/app/Marina/DataAccess/IDatabaseConfiguration.cs create mode 100644 slips/src/app/Marina/DataAccess/IDatabaseConnection.cs create mode 100644 slips/src/app/Marina/DataAccess/IDatabaseConnectionFactory.cs create mode 100644 slips/src/app/Marina/DataAccess/IDatabaseGateway.cs create mode 100644 slips/src/app/Marina/DataAccess/IDatabaseProviderFactory.cs create mode 100644 slips/src/app/Marina/DataAccess/IDatabaseRow.cs create mode 100644 slips/src/app/Marina/DataAccess/IDatabaseTransaction.cs create mode 100644 slips/src/app/Marina/DataAccess/IIdentityMap.cs create mode 100644 slips/src/app/Marina/DataAccess/IdentityMap.cs create mode 100644 slips/src/app/Marina/DataAccess/Repositories/CustomerRepository.cs create mode 100644 slips/src/app/Marina/DataAccess/Repositories/DockRepository.cs create mode 100644 slips/src/app/Marina/DataAccess/Repositories/SlipsRepository.cs create mode 100644 slips/src/app/Marina/DataAccess/Schemas/AuthorizationTable.cs create mode 100644 slips/src/app/Marina/DataAccess/Schemas/BoatTable.cs create mode 100644 slips/src/app/Marina/DataAccess/Schemas/CustomerTable.cs create mode 100644 slips/src/app/Marina/DataAccess/Schemas/DockTable.cs create mode 100644 slips/src/app/Marina/DataAccess/Schemas/LeaseTable.cs create mode 100644 slips/src/app/Marina/DataAccess/Schemas/LeaseType.cs create mode 100644 slips/src/app/Marina/DataAccess/Schemas/LocationTable.cs create mode 100644 slips/src/app/Marina/DataAccess/Schemas/SlipTable.cs create mode 100644 slips/src/app/Marina/Domain/Boat.cs create mode 100644 slips/src/app/Marina/Domain/BrokenRule.cs create mode 100644 slips/src/app/Marina/Domain/Customer.cs create mode 100644 slips/src/app/Marina/Domain/CustomerRegistration.cs create mode 100644 slips/src/app/Marina/Domain/DateRange.cs create mode 100644 slips/src/app/Marina/Domain/Dock.cs create mode 100644 slips/src/app/Marina/Domain/DomainObject.cs create mode 100644 slips/src/app/Marina/Domain/Exceptions/SlipIsAlreadyLeasedException.cs create mode 100644 slips/src/app/Marina/Domain/Interfaces/IBoat.cs create mode 100644 slips/src/app/Marina/Domain/Interfaces/IBrokenRule.cs create mode 100644 slips/src/app/Marina/Domain/Interfaces/IBusinessRule.cs create mode 100644 slips/src/app/Marina/Domain/Interfaces/ICustomer.cs create mode 100644 slips/src/app/Marina/Domain/Interfaces/IDateRange.cs create mode 100644 slips/src/app/Marina/Domain/Interfaces/IDock.cs create mode 100644 slips/src/app/Marina/Domain/Interfaces/IDomainObject.cs create mode 100644 slips/src/app/Marina/Domain/Interfaces/ILeaseDuration.cs create mode 100644 slips/src/app/Marina/Domain/Interfaces/ILeaseType.cs create mode 100644 slips/src/app/Marina/Domain/Interfaces/ILocation.cs create mode 100644 slips/src/app/Marina/Domain/Interfaces/IRange.cs create mode 100644 slips/src/app/Marina/Domain/Interfaces/IRegistration.cs create mode 100644 slips/src/app/Marina/Domain/Interfaces/ISlip.cs create mode 100644 slips/src/app/Marina/Domain/Interfaces/ISlipLease.cs create mode 100644 slips/src/app/Marina/Domain/Interfaces/IUtility.cs create mode 100644 slips/src/app/Marina/Domain/LeaseDurations.cs create mode 100644 slips/src/app/Marina/Domain/Location.cs create mode 100644 slips/src/app/Marina/Domain/Range.cs create mode 100644 slips/src/app/Marina/Domain/Repositories/ICustomerRepository.cs create mode 100644 slips/src/app/Marina/Domain/Repositories/IDockRepository.cs create mode 100644 slips/src/app/Marina/Domain/Repositories/ISlipsRepository.cs create mode 100644 slips/src/app/Marina/Domain/Slip.cs create mode 100644 slips/src/app/Marina/Domain/SlipLease.cs create mode 100644 slips/src/app/Marina/Domain/UnknownCustomer.cs create mode 100644 slips/src/app/Marina/Domain/Utilities.cs create mode 100644 slips/src/app/Marina/Infrastructure/BlankCommand.cs create mode 100644 slips/src/app/Marina/Infrastructure/Configuration/ConfigurationItem.cs create mode 100644 slips/src/app/Marina/Infrastructure/Configuration/ConfigurationItems.cs create mode 100644 slips/src/app/Marina/Infrastructure/Container/Custom/CustomDependencyContainer.cs create mode 100644 slips/src/app/Marina/Infrastructure/Container/IDependencyContainer.cs create mode 100644 slips/src/app/Marina/Infrastructure/Container/InterfaceResolutionException.cs create mode 100644 slips/src/app/Marina/Infrastructure/Container/Resolve.cs create mode 100644 slips/src/app/Marina/Infrastructure/Container/Windsor/WindsorDependencyContainer.cs create mode 100644 slips/src/app/Marina/Infrastructure/EnumerableMapper.cs create mode 100644 slips/src/app/Marina/Infrastructure/ICommand.cs create mode 100644 slips/src/app/Marina/Infrastructure/IFactory.cs create mode 100644 slips/src/app/Marina/Infrastructure/IMapper.cs create mode 100644 slips/src/app/Marina/Infrastructure/IRichEnumerable.cs create mode 100644 slips/src/app/Marina/Infrastructure/IRichList.cs create mode 100644 slips/src/app/Marina/Infrastructure/ISpecification.cs create mode 100644 slips/src/app/Marina/Infrastructure/ISpecificationBuilder.cs create mode 100644 slips/src/app/Marina/Infrastructure/ITransformer.cs create mode 100644 slips/src/app/Marina/Infrastructure/IValueReturningVisitor.cs create mode 100644 slips/src/app/Marina/Infrastructure/IVisitor.cs create mode 100644 slips/src/app/Marina/Infrastructure/ListFactory.cs create mode 100644 slips/src/app/Marina/Infrastructure/Logging/Interfaces/ILog.cs create mode 100644 slips/src/app/Marina/Infrastructure/Logging/Interfaces/ILogFactory.cs create mode 100644 slips/src/app/Marina/Infrastructure/Logging/Interfaces/Log.cs create mode 100644 slips/src/app/Marina/Infrastructure/Logging/Log4Net/ILog4NetInitializationCommand.cs create mode 100644 slips/src/app/Marina/Infrastructure/Logging/Log4Net/Log4NetInitializationCommand.cs create mode 100644 slips/src/app/Marina/Infrastructure/Logging/Log4Net/Log4NetLog.cs create mode 100644 slips/src/app/Marina/Infrastructure/Logging/Log4Net/Log4NetLogFactory.cs create mode 100644 slips/src/app/Marina/Infrastructure/Logging/TextWriterLogging/TextWriterLog.cs create mode 100644 slips/src/app/Marina/Infrastructure/Logging/TextWriterLogging/TextWriterLogFactory.cs create mode 100644 slips/src/app/Marina/Infrastructure/RichEnumerable.cs create mode 100644 slips/src/app/Marina/Infrastructure/RichList.cs create mode 100644 slips/src/app/Marina/Infrastructure/SpecificationBuilder.cs create mode 100644 slips/src/app/Marina/Infrastructure/Transform.cs create mode 100644 slips/src/app/Marina/Infrastructure/Transformer.cs create mode 100644 slips/src/app/Marina/Marina.csproj create mode 100644 slips/src/app/Marina/Presentation/DTO/BoatRegistrationDTO.cs create mode 100644 slips/src/app/Marina/Presentation/DTO/CustomerRegistrationDisplayDTO.cs create mode 100644 slips/src/app/Marina/Presentation/DTO/DisplayLeaseDTO.cs create mode 100644 slips/src/app/Marina/Presentation/DTO/DisplayResponseLineDTO.cs create mode 100644 slips/src/app/Marina/Presentation/DTO/DisplayResponseLines.cs create mode 100644 slips/src/app/Marina/Presentation/DTO/DockDisplayDTO.cs create mode 100644 slips/src/app/Marina/Presentation/DTO/LoginCredentialsDTO.cs create mode 100644 slips/src/app/Marina/Presentation/DTO/RegisterCustomerDTO.cs create mode 100644 slips/src/app/Marina/Presentation/DTO/SlipDisplayDTO.cs create mode 100644 slips/src/app/Marina/Presentation/DTO/SubmitLeaseRequestDTO.cs create mode 100644 slips/src/app/Marina/Presentation/DTO/UpdateCustomerRegistrationDTO.cs create mode 100644 slips/src/app/Marina/Presentation/Mappers/CustomerRegistrationPresentationMapper.cs create mode 100644 slips/src/app/Marina/Presentation/Mappers/ICustomerRegistrationPresentationMapper.cs create mode 100644 slips/src/app/Marina/Presentation/Mappers/ILeaseRequestDtoFromHttpRequestMapper.cs create mode 100644 slips/src/app/Marina/Presentation/Mappers/ILoginCredentialsMapper.cs create mode 100644 slips/src/app/Marina/Presentation/Mappers/INewBoatRegistrationMapper.cs create mode 100644 slips/src/app/Marina/Presentation/Mappers/IUpdateRegistrationPresentationMapper.cs create mode 100644 slips/src/app/Marina/Presentation/Mappers/LeaseRequestDtoFromHttpRequestMapper.cs create mode 100644 slips/src/app/Marina/Presentation/Mappers/LoginCredentialsMapper.cs create mode 100644 slips/src/app/Marina/Presentation/Mappers/NewBoatRegistrationMapper.cs create mode 100644 slips/src/app/Marina/Presentation/Mappers/UpdateRegistrationPresentationMapper.cs create mode 100644 slips/src/app/Marina/Presentation/PayLoadKeys.cs create mode 100644 slips/src/app/Marina/Presentation/PayloadKey.cs create mode 100644 slips/src/app/Marina/Presentation/PayloadKeyNotFoundException.cs create mode 100644 slips/src/app/Marina/Presentation/Presenters/AvailableSlipsPresenter.cs create mode 100644 slips/src/app/Marina/Presentation/Presenters/CurrentLeasesPresenter.cs create mode 100644 slips/src/app/Marina/Presentation/Presenters/CustomerRegistrationPresenter.cs create mode 100644 slips/src/app/Marina/Presentation/Presenters/DockPresenter.cs create mode 100644 slips/src/app/Marina/Presentation/Presenters/IAvailableSlipsPresenter.cs create mode 100644 slips/src/app/Marina/Presentation/Presenters/ICurrentLeasesPresenter.cs create mode 100644 slips/src/app/Marina/Presentation/Presenters/ICustomerRegistrationPresenter.cs create mode 100644 slips/src/app/Marina/Presentation/Presenters/IDockPresenter.cs create mode 100644 slips/src/app/Marina/Presentation/Presenters/ILeaseSlipPresenter.cs create mode 100644 slips/src/app/Marina/Presentation/Presenters/ILoginPresenter.cs create mode 100644 slips/src/app/Marina/Presentation/Presenters/IRegisterBoatPresenter.cs create mode 100644 slips/src/app/Marina/Presentation/Presenters/IUpdateCustomerRegistrationPresenter.cs create mode 100644 slips/src/app/Marina/Presentation/Presenters/IViewRegisteredBoatsPresenter.cs create mode 100644 slips/src/app/Marina/Presentation/Presenters/LeaseSlipPresenter.cs create mode 100644 slips/src/app/Marina/Presentation/Presenters/LoginPresenter.cs create mode 100644 slips/src/app/Marina/Presentation/Presenters/RegisterBoatPresenter.cs create mode 100644 slips/src/app/Marina/Presentation/Presenters/UpdateCustomerRegistrationPresenter.cs create mode 100644 slips/src/app/Marina/Presentation/Presenters/ViewRegisteredBoatsPresenter.cs create mode 100644 slips/src/app/Marina/Presentation/Views/IAvailableSlipsView.cs create mode 100644 slips/src/app/Marina/Presentation/Views/ICurrentLeasesView.cs create mode 100644 slips/src/app/Marina/Presentation/Views/ICustomerRegistrationView.cs create mode 100644 slips/src/app/Marina/Presentation/Views/IDockView.cs create mode 100644 slips/src/app/Marina/Presentation/Views/ILeaseSlipView.cs create mode 100644 slips/src/app/Marina/Presentation/Views/ILoginView.cs create mode 100644 slips/src/app/Marina/Presentation/Views/IRegisterBoatView.cs create mode 100644 slips/src/app/Marina/Presentation/Views/IRegisteredBoatsView.cs create mode 100644 slips/src/app/Marina/Presentation/Views/IUpdateRegistrationView.cs create mode 100644 slips/src/app/Marina/Properties/AssemblyInfo.cs create mode 100644 slips/src/app/Marina/Task/ApplicationStartupTask.cs create mode 100644 slips/src/app/Marina/Task/AuthenticationTask.cs create mode 100644 slips/src/app/Marina/Task/CatalogTasks.cs create mode 100644 slips/src/app/Marina/Task/IApplicationStartupTask.cs create mode 100644 slips/src/app/Marina/Task/IAuthenticationTask.cs create mode 100644 slips/src/app/Marina/Task/ICatalogTasks.cs create mode 100644 slips/src/app/Marina/Task/ILeaseTasks.cs create mode 100644 slips/src/app/Marina/Task/IRegistrationTasks.cs create mode 100644 slips/src/app/Marina/Task/LeaseTasks.cs create mode 100644 slips/src/app/Marina/Task/Mappers/BrokenRulesToDisplayItemMapper.cs create mode 100644 slips/src/app/Marina/Task/Mappers/DockToDisplayDTOMapper.cs create mode 100644 slips/src/app/Marina/Task/Mappers/IBrokenRulesToDisplayItemMapper.cs create mode 100644 slips/src/app/Marina/Task/Mappers/IDockToDisplayDTOMapper.cs create mode 100644 slips/src/app/Marina/Task/Mappers/ILeaseToDtoMapper.cs create mode 100644 slips/src/app/Marina/Task/Mappers/ISlipsToDisplayDTOMapper.cs create mode 100644 slips/src/app/Marina/Task/Mappers/LeaseToDtoMapper.cs create mode 100644 slips/src/app/Marina/Task/Mappers/SlipsToDisplayDTOMapper.cs create mode 100644 slips/src/app/Marina/Task/RegistrationTasks.cs create mode 100644 slips/src/app/Marina/Web/AuthenticationHttpModule.cs create mode 100644 slips/src/app/Marina/Web/Commands/AvailableSlipsCommand.cs create mode 100644 slips/src/app/Marina/Web/Commands/CommandNames.cs create mode 100644 slips/src/app/Marina/Web/Commands/RedirectCommand.cs create mode 100644 slips/src/app/Marina/Web/CurrentHttpContext.cs create mode 100644 slips/src/app/Marina/Web/CurrentHttpRequest.cs create mode 100644 slips/src/app/Marina/Web/FrontController.cs create mode 100644 slips/src/app/Marina/Web/GlobalApplication.cs create mode 100644 slips/src/app/Marina/Web/Handlers/AvailableSlipsHandler.cs create mode 100644 slips/src/app/Marina/Web/Handlers/Dispatcher.cs create mode 100644 slips/src/app/Marina/Web/Handlers/IRegisteredHandlers.cs create mode 100644 slips/src/app/Marina/Web/Handlers/IRequestHandler.cs create mode 100644 slips/src/app/Marina/Web/Handlers/RegisteredHandlers.cs create mode 100644 slips/src/app/Marina/Web/Handlers/RequestHandler.cs create mode 100644 slips/src/app/Marina/Web/Handlers/RequestHandlerSpecification.cs create mode 100644 slips/src/app/Marina/Web/Http/HttpGateway.cs create mode 100644 slips/src/app/Marina/Web/Http/IHttpGateway.cs create mode 100644 slips/src/app/Marina/Web/IHttpContext.cs create mode 100644 slips/src/app/Marina/Web/IHttpRequest.cs create mode 100644 slips/src/app/Marina/Web/Redirect.cs create mode 100644 slips/src/app/Marina/Web/Services/AuthenticationServices.asmx create mode 100644 slips/src/app/Marina/Web/Services/AuthenticationWebServices.cs create mode 100644 slips/src/app/Marina/Web/Services/CatalogServices.asmx create mode 100644 slips/src/app/Marina/Web/Services/CatalogWebServices.cs create mode 100644 slips/src/app/Marina/Web/Services/LeaseServices.asmx create mode 100644 slips/src/app/Marina/Web/Services/LeaseWebServices.cs create mode 100644 slips/src/app/Marina/Web/Services/RegistrationServices.asmx create mode 100644 slips/src/app/Marina/Web/Services/RegistrationWebServices.cs create mode 100644 slips/src/app/Marina/Web/UnhandledExceptionsHttpModule.cs create mode 100644 slips/src/app/Marina/Web/Views/IView.cs create mode 100644 slips/src/app/Marina/Web/Views/IViewLuggageTicket.cs create mode 100644 slips/src/app/Marina/Web/Views/IViewLuggageTransporter.cs create mode 100644 slips/src/app/Marina/Web/Views/IWebView.cs create mode 100644 slips/src/app/Marina/Web/Views/Pages/AvailableSlipsWebView.cs create mode 100644 slips/src/app/Marina/Web/Views/Pages/IAvailableSlipsWebView.cs create mode 100644 slips/src/app/Marina/Web/Views/View.cs create mode 100644 slips/src/app/Marina/Web/Views/ViewLuggage.cs create mode 100644 slips/src/app/Marina/Web/Views/ViewLuggageTickets.cs create mode 100644 slips/src/app/Marina/Web/Views/ViewLuggageTransporter.cs create mode 100644 slips/src/app/Marina/Web/Views/WebView.cs create mode 100644 slips/src/app/Marina/Web/Views/WebViews.cs create mode 100644 slips/src/test/Marina.Test/Integration/DataAccess/Mappers/BoatDataMapperTest.cs create mode 100644 slips/src/test/Marina.Test/Integration/DataAccess/Mappers/CustomerDataMapperTest.cs create mode 100644 slips/src/test/Marina.Test/Integration/DataAccess/Mappers/LeaseDataMapperTest.cs create mode 100644 slips/src/test/Marina.Test/Integration/DataAccess/Mappers/RegistrationDataMapperTest.cs create mode 100644 slips/src/test/Marina.Test/Integration/DataAccess/Repositories/DockRepositoryTest.cs create mode 100644 slips/src/test/Marina.Test/Integration/DataAccess/Repositories/SlipRepositoryTest.cs create mode 100644 slips/src/test/Marina.Test/Integration/DataAccess/Utility/BoatMother.cs create mode 100644 slips/src/test/Marina.Test/Integration/DataAccess/Utility/CustomerMother.cs create mode 100644 slips/src/test/Marina.Test/Integration/DataAccess/Utility/LeaseMother.cs create mode 100644 slips/src/test/Marina.Test/Integration/DataAccess/Utility/SlipMother.cs create mode 100644 slips/src/test/Marina.Test/Integration/Task/CatalogTasksTest.cs create mode 100644 slips/src/test/Marina.Test/Marina.Test.csproj create mode 100644 slips/src/test/Marina.Test/Properties/AssemblyInfo.cs create mode 100644 slips/src/test/Marina.Test/Unit/DataAccess/DatabaseCommandTest.cs create mode 100644 slips/src/test/Marina.Test/Unit/DataAccess/DatabaseConfigurationTest.cs create mode 100644 slips/src/test/Marina.Test/Unit/DataAccess/DatabaseConnectionTest.cs create mode 100644 slips/src/test/Marina.Test/Unit/DataAccess/DatabaseGatewayTest.cs create mode 100644 slips/src/test/Marina.Test/Unit/DataAccess/Mappers/CustomerDataMapperTest.cs create mode 100644 slips/src/test/Marina.Test/Unit/DataAccess/Repositories/CustomerRepositoryTest.cs create mode 100644 slips/src/test/Marina.Test/Unit/DataAccess/Repositories/DockRepositoryTest.cs create mode 100644 slips/src/test/Marina.Test/Unit/DataAccess/Repositories/IdentityMapTest.cs create mode 100644 slips/src/test/Marina.Test/Unit/DataAccess/Repositories/SlipRepositoryTest.cs create mode 100644 slips/src/test/Marina.Test/Unit/Domain/CustomerRegistrationTest.cs create mode 100644 slips/src/test/Marina.Test/Unit/Domain/CustomerTest.cs create mode 100644 slips/src/test/Marina.Test/Unit/Domain/DockTest.cs create mode 100644 slips/src/test/Marina.Test/Unit/Domain/LeaseDurationTest.cs create mode 100644 slips/src/test/Marina.Test/Unit/Domain/SlipTest.cs create mode 100644 slips/src/test/Marina.Test/Unit/Domain/UtilitiesTest.cs create mode 100644 slips/src/test/Marina.Test/Unit/Infrastructure/Logging/Interfaces/LogTest.cs create mode 100644 slips/src/test/Marina.Test/Unit/Infrastructure/Logging/TextWriterLogging/TextWriterLogFactoryTest.cs create mode 100644 slips/src/test/Marina.Test/Unit/Infrastructure/Logging/TextWriterLogging/TextWriterLogTest.cs create mode 100644 slips/src/test/Marina.Test/Unit/Infrastructure/TransformTest.cs create mode 100644 slips/src/test/Marina.Test/Unit/Presentation/AvailableSlipsPresenterTest.cs create mode 100644 slips/src/test/Marina.Test/Unit/Presentation/CurrentLeasesPresenterTest.cs create mode 100644 slips/src/test/Marina.Test/Unit/Presentation/CustomerRegistrationPresenterTest.cs create mode 100644 slips/src/test/Marina.Test/Unit/Presentation/DockPresenterTest.cs create mode 100644 slips/src/test/Marina.Test/Unit/Presentation/LeaseSlipPresenterTest.cs create mode 100644 slips/src/test/Marina.Test/Unit/Presentation/LoginPresenterTest.cs create mode 100644 slips/src/test/Marina.Test/Unit/Presentation/Mappers/CustomerRegistrationPresentationMapperTest.cs create mode 100644 slips/src/test/Marina.Test/Unit/Presentation/Mappers/LoginCredentialsMapperTest.cs create mode 100644 slips/src/test/Marina.Test/Unit/Presentation/Mappers/UpdateRegistrationPresentationMapperTest.cs create mode 100644 slips/src/test/Marina.Test/Unit/Presentation/PayloadKeyTest.cs create mode 100644 slips/src/test/Marina.Test/Unit/Presentation/RegisterBoatPresenterTest.cs create mode 100644 slips/src/test/Marina.Test/Unit/Presentation/UpdateRegistrationPresenterTest.cs create mode 100644 slips/src/test/Marina.Test/Unit/Presentation/ViewRegisteredBoatsPresenterTest.cs create mode 100644 slips/src/test/Marina.Test/Unit/Task/CatalogTasksTest.cs create mode 100644 slips/src/test/Marina.Test/Unit/Task/LeaseTasksTest.cs create mode 100644 slips/src/test/Marina.Test/Unit/Task/RegistrationTasksTest.cs create mode 100644 slips/src/test/Marina.Test/Unit/Web/Commands/AvailableSlipsCommandTest.cs create mode 100644 slips/src/test/Marina.Test/Unit/Web/Handlers/RequestHandlerSpecificationTest.cs create mode 100644 slips/src/test/Marina.Test/Unit/Web/Handlers/RequestHandlerTest.cs create mode 100644 slips/src/test/Marina.Test/Unit/Web/Views/Pages/AvailableSlipsWebViewTest.cs create mode 100644 slips/src/test/Marina.Test/Unit/Web/Views/ViewTest.cs create mode 100644 slips/src/test/Marina.Test/Utility/ObjectMother.cs create mode 100644 slips/src/test/Marina.Test/Utility/RunInRealContainerAttribute.cs create mode 100644 slips/src/test/Marina.Test/Utility/RunInRealContainerRunInvoker.cs (limited to 'slips/src') diff --git a/slips/src/app/Marina.Web.UI/AvailableSlips.aspx b/slips/src/app/Marina.Web.UI/AvailableSlips.aspx new file mode 100644 index 0000000..b89697f --- /dev/null +++ b/slips/src/app/Marina.Web.UI/AvailableSlips.aspx @@ -0,0 +1,37 @@ +<%@ Page Language="C#" MasterPageFile="~/Site.Master" AutoEventWireup="true" CodeBehind="AvailableSlips.aspx.cs" Inherits="Marina.Web.UI.AvailableSlips" Title="Untitled Page" %> +<%@ Import namespace="Marina.Web.Views"%> + +<%@ Import namespace="Marina.Presentation"%> +<%@ Import namespace="Marina.Presentation.DTO"%> +<%@ Import namespace="Marina.Infrastructure"%> + + + +
+

Available Slips

+ + + + + + + + + + + <% foreach ( SlipDisplayDTO item in ViewLuggage.ClaimFor(ViewLuggageTickets.AvailableSlips) ) {%> + + + + + + + <% } %> + +
Location NameDock NameSlip WidthSlip Length
<%= item.LocationName %> + + <%= item.DockName %> + + <%= item.Width %><%= item.Length %>
+
+
diff --git a/slips/src/app/Marina.Web.UI/AvailableSlips.aspx.cs b/slips/src/app/Marina.Web.UI/AvailableSlips.aspx.cs new file mode 100644 index 0000000..0166217 --- /dev/null +++ b/slips/src/app/Marina.Web.UI/AvailableSlips.aspx.cs @@ -0,0 +1,21 @@ +using System; +using System.Collections.Generic; +using System.Web.UI; +using Marina.Presentation.DTO; +using Marina.Presentation.Presenters; +using Marina.Presentation.Views; +using Marina.Web.Views; + +namespace Marina.Web.UI { + public partial class AvailableSlips : Page, IAvailableSlipsView { + protected override void OnInit( EventArgs e ) { + base.OnInit( e ); + + new AvailableSlipsPresenter( this ).Initialize( ); + } + + public void Display( IEnumerable< SlipDisplayDTO > availableSlips ) { + ViewLuggage.TransporterFor( ViewLuggageTickets.AvailableSlips ).Add( availableSlips ); + } + } +} \ No newline at end of file diff --git a/slips/src/app/Marina.Web.UI/AvailableSlips.aspx.designer.cs b/slips/src/app/Marina.Web.UI/AvailableSlips.aspx.designer.cs new file mode 100644 index 0000000..2710f03 --- /dev/null +++ b/slips/src/app/Marina.Web.UI/AvailableSlips.aspx.designer.cs @@ -0,0 +1,16 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:2.0.50727.1433 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace Marina.Web.UI { + + + public partial class AvailableSlips { + } +} diff --git a/slips/src/app/Marina.Web.UI/ContactUs.aspx b/slips/src/app/Marina.Web.UI/ContactUs.aspx new file mode 100644 index 0000000..84028f2 --- /dev/null +++ b/slips/src/app/Marina.Web.UI/ContactUs.aspx @@ -0,0 +1,23 @@ +<%@ Page Language="C#" MasterPageFile="~/Site.Master" AutoEventWireup="true" CodeBehind="ContactUs.aspx.cs" Inherits="Marina.Web.UI.ContactUs" Title="Untitled Page" %> + + + + +

Contact Info

+

+ Inland Lake Marina
+ Box 123
+ Inland Lake, Arizona
+ 86038 +

+

+ (office ph) 928-450-2234
+ (leasing ph) 928-450-2235
+ (fax) 928-450-2236
+

+

+ Manager: Glenn Cooke
+ Slip Manager: Kimberley Carson
+ Contact Email: info@inlandmarina.com +

+
diff --git a/slips/src/app/Marina.Web.UI/ContactUs.aspx.cs b/slips/src/app/Marina.Web.UI/ContactUs.aspx.cs new file mode 100644 index 0000000..e59693c --- /dev/null +++ b/slips/src/app/Marina.Web.UI/ContactUs.aspx.cs @@ -0,0 +1,8 @@ +using System; +using System.Web.UI; + +namespace Marina.Web.UI { + public partial class ContactUs : Page { + protected void Page_Load( object sender, EventArgs e ) {} + } +} \ No newline at end of file diff --git a/slips/src/app/Marina.Web.UI/ContactUs.aspx.designer.cs b/slips/src/app/Marina.Web.UI/ContactUs.aspx.designer.cs new file mode 100644 index 0000000..77f29cc --- /dev/null +++ b/slips/src/app/Marina.Web.UI/ContactUs.aspx.designer.cs @@ -0,0 +1,16 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:2.0.50727.1433 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace Marina.Web.UI { + + + public partial class ContactUs { + } +} diff --git a/slips/src/app/Marina.Web.UI/CurrentLeases.aspx b/slips/src/app/Marina.Web.UI/CurrentLeases.aspx new file mode 100644 index 0000000..0fb1bc5 --- /dev/null +++ b/slips/src/app/Marina.Web.UI/CurrentLeases.aspx @@ -0,0 +1,28 @@ +<%@ Page Language="C#" MasterPageFile="~/Site.Master" AutoEventWireup="true" CodeBehind="CurrentLeases.aspx.cs" Inherits="Marina.Web.UI.CurrentLeases" Title="Untitled Page" %> +<%@ Import namespace="Marina.Presentation.DTO"%> +<%@ Import namespace="Marina.Infrastructure"%> + + + +

Current Leases

+ + + + + + + + + + + + + + + + + +
Slip IDStart Date:Expiry Date:
<%# Transform.From( Container.DataItem).To( ).SlipID %><%# Transform.From( Container.DataItem).To( ).StartDate %><%# Transform.From( Container.DataItem).To( ).ExpiryDate %>
+ +
+
diff --git a/slips/src/app/Marina.Web.UI/CurrentLeases.aspx.cs b/slips/src/app/Marina.Web.UI/CurrentLeases.aspx.cs new file mode 100644 index 0000000..47b2951 --- /dev/null +++ b/slips/src/app/Marina.Web.UI/CurrentLeases.aspx.cs @@ -0,0 +1,19 @@ +using System; +using System.Collections.Generic; +using System.Web.UI; +using Marina.Presentation.DTO; +using Marina.Presentation.Presenters; +using Marina.Presentation.Views; + +namespace Marina.Web.UI { + public partial class CurrentLeases : Page, ICurrentLeasesView { + protected void Page_Load( object sender, EventArgs e ) { + new CurrentLeasesPresenter( this ).Initialize( ); + } + + public void Display( IEnumerable< DisplayLeaseDTO > leases ) { + uxLeasesRepeater.DataSource = leases; + uxLeasesRepeater.DataBind( ); + } + } +} \ No newline at end of file diff --git a/slips/src/app/Marina.Web.UI/CurrentLeases.aspx.designer.cs b/slips/src/app/Marina.Web.UI/CurrentLeases.aspx.designer.cs new file mode 100644 index 0000000..68acd07 --- /dev/null +++ b/slips/src/app/Marina.Web.UI/CurrentLeases.aspx.designer.cs @@ -0,0 +1,25 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:2.0.50727.1433 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace Marina.Web.UI { + + + public partial class CurrentLeases { + + /// + /// uxLeasesRepeater control. + /// + /// + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// + protected global::System.Web.UI.WebControls.Repeater uxLeasesRepeater; + } +} diff --git a/slips/src/app/Marina.Web.UI/Default.aspx b/slips/src/app/Marina.Web.UI/Default.aspx new file mode 100644 index 0000000..dd7f233 --- /dev/null +++ b/slips/src/app/Marina.Web.UI/Default.aspx @@ -0,0 +1,19 @@ +<%@ Page Language="C#" MasterPageFile="~/Site.Master" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="Marina.Web.UI.Default" Title="Untitled Page" %> + + + +

Welcome

+

+ Welcome to Inland Marina located on the south shore Inland Lake, just a small + commute from major centres in the south west. +

+

+ Inland Marina was established in the 1967 shortly after Inland Lake was created + as a result of the South West damn. From it's humble beginnings, it has grown to + be the largest marina on Inland Lake. Due to the warm climate that extends year + round, Inland Lake has become a popular tourist destination in the South West. + Boat owners from California, Arizona, Nevada, and Utah are attracted to the + area. Inland Marina has 150 slips ranging in size from 16 to 28 feet in length. + Dock services include electrical and fresh water. +

+
diff --git a/slips/src/app/Marina.Web.UI/Default.aspx.cs b/slips/src/app/Marina.Web.UI/Default.aspx.cs new file mode 100644 index 0000000..9a6cecc --- /dev/null +++ b/slips/src/app/Marina.Web.UI/Default.aspx.cs @@ -0,0 +1,8 @@ +using System; +using System.Web.UI; + +namespace Marina.Web.UI { + public partial class Default : Page { + protected void Page_Load( object sender, EventArgs e ) {} + } +} \ No newline at end of file diff --git a/slips/src/app/Marina.Web.UI/Default.aspx.designer.cs b/slips/src/app/Marina.Web.UI/Default.aspx.designer.cs new file mode 100644 index 0000000..b6d29bc --- /dev/null +++ b/slips/src/app/Marina.Web.UI/Default.aspx.designer.cs @@ -0,0 +1,16 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:2.0.50727.1433 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace Marina.Web.UI { + + + public partial class Default { + } +} diff --git a/slips/src/app/Marina.Web.UI/DockView.aspx b/slips/src/app/Marina.Web.UI/DockView.aspx new file mode 100644 index 0000000..10d06f7 --- /dev/null +++ b/slips/src/app/Marina.Web.UI/DockView.aspx @@ -0,0 +1,60 @@ +<%@ Page Language="C#" MasterPageFile="~/Site.Master" AutoEventWireup="true" CodeBehind="DockView.aspx.cs" Inherits="Marina.Web.UI.DockView" Title="Untitled Page" %> +<%@ Import namespace="System.ComponentModel"%> +<%@ Import namespace="Marina.Web.Commands"%> +<%@ Import namespace="Marina.Web.Views"%> + +<%@ Import namespace="Marina.Presentation.DTO"%> +<%@ Import namespace="Marina.Infrastructure"%> +<%@ Import namespace="Marina.Presentation"%> + + + +
+

Dock: <%= DTO.Name %>

+ + + + + + + + + + + + + +
Location<%= DTO.LocationName %>
Water Service<%= DTO.WaterService %>
Electrical Service<%= DTO.ElectricalService %>
+
+
+

Available Slips

+ + + + + + + + + + + + + + + + + + + + + +
Dock NameSlip WidthSlip Length
<%# Transform.From(Container.DataItem).To().DockName %><%# Transform.From(Container.DataItem).To().Width %><%# Transform.From(Container.DataItem).To().Length %>Lease This Slip!
+ +
+
+
+ View All Available Slips +
+ +
diff --git a/slips/src/app/Marina.Web.UI/DockView.aspx.cs b/slips/src/app/Marina.Web.UI/DockView.aspx.cs new file mode 100644 index 0000000..722d2c5 --- /dev/null +++ b/slips/src/app/Marina.Web.UI/DockView.aspx.cs @@ -0,0 +1,26 @@ +using System; +using System.Collections.Generic; +using System.Web.UI; +using Marina.Presentation.DTO; +using Marina.Presentation.Presenters; +using Marina.Presentation.Views; + +namespace Marina.Web.UI { + public partial class DockView : Page, IDockView { + protected DockDisplayDTO DTO; + + protected override void OnInit( EventArgs e ) { + base.OnInit( e ); + new DockPresenter( this ).Initialize( ); + } + + public void Display( DockDisplayDTO dto ) { + DTO = dto; + } + + public void Display( IEnumerable< SlipDisplayDTO > availableSlips ) { + uxSlipsRepeater.DataSource = availableSlips; + uxSlipsRepeater.DataBind( ); + } + } +} \ No newline at end of file diff --git a/slips/src/app/Marina.Web.UI/DockView.aspx.designer.cs b/slips/src/app/Marina.Web.UI/DockView.aspx.designer.cs new file mode 100644 index 0000000..a4f5686 --- /dev/null +++ b/slips/src/app/Marina.Web.UI/DockView.aspx.designer.cs @@ -0,0 +1,25 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:2.0.50727.1433 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace Marina.Web.UI { + + + public partial class DockView { + + /// + /// uxSlipsRepeater control. + /// + /// + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// + protected global::System.Web.UI.WebControls.Repeater uxSlipsRepeater; + } +} diff --git a/slips/src/app/Marina.Web.UI/Global.asax b/slips/src/app/Marina.Web.UI/Global.asax new file mode 100644 index 0000000..7b78699 --- /dev/null +++ b/slips/src/app/Marina.Web.UI/Global.asax @@ -0,0 +1 @@ +<%@ Application Language="C#" Inherits="Marina.Web.GlobalApplication"%> diff --git a/slips/src/app/Marina.Web.UI/LeaseSlip.aspx b/slips/src/app/Marina.Web.UI/LeaseSlip.aspx new file mode 100644 index 0000000..260aa10 --- /dev/null +++ b/slips/src/app/Marina.Web.UI/LeaseSlip.aspx @@ -0,0 +1,46 @@ +<%@ Page Language="C#" MasterPageFile="~/Site.Master" AutoEventWireup="true" CodeBehind="LeaseSlip.aspx.cs" Inherits="Marina.Web.UI.LeaseSlip" Title="Untitled Page" %> + + + + +

Would you like to lease slip: <%= Slip.SlipId %>

+ +
+ + + + + + + + + + + + + + + + + +
Dock NameLocation NameLength (in feet)Width (in feet)
<%= Slip.DockName %><%= Slip.LocationName %><%= Slip.Length %><%= Slip.Width %>
+
+ +
+ Select Lease Duration: + +
+ + + +

+ <%= ResponseMessage %> +

+ +
+ diff --git a/slips/src/app/Marina.Web.UI/LeaseSlip.aspx.cs b/slips/src/app/Marina.Web.UI/LeaseSlip.aspx.cs new file mode 100644 index 0000000..c5ead9b --- /dev/null +++ b/slips/src/app/Marina.Web.UI/LeaseSlip.aspx.cs @@ -0,0 +1,26 @@ +using System; +using System.Web.UI; +using Marina.Presentation.DTO; +using Marina.Presentation.Presenters; +using Marina.Presentation.Views; + +namespace Marina.Web.UI { + public partial class LeaseSlip : Page, ILeaseSlipView { + protected void Page_Load( object sender, EventArgs e ) { + ILeaseSlipPresenter presenter = new LeaseSlipPresenter( this ); + presenter.Initialize( ); + uxSubmitButton.Click += delegate { presenter.SubmitLeaseRequest( ); }; + } + + public SlipDisplayDTO Slip; + public string ResponseMessage; + + public void Display( SlipDisplayDTO slip ) { + Slip = slip; + } + + public void Display( DisplayResponseLineDTO response ) { + ResponseMessage = response.Message; + } + } +} \ No newline at end of file diff --git a/slips/src/app/Marina.Web.UI/LeaseSlip.aspx.designer.cs b/slips/src/app/Marina.Web.UI/LeaseSlip.aspx.designer.cs new file mode 100644 index 0000000..0f28679 --- /dev/null +++ b/slips/src/app/Marina.Web.UI/LeaseSlip.aspx.designer.cs @@ -0,0 +1,25 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:2.0.50727.1433 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace Marina.Web.UI { + + + public partial class LeaseSlip { + + /// + /// uxSubmitButton control. + /// + /// + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// + protected global::System.Web.UI.WebControls.Button uxSubmitButton; + } +} diff --git a/slips/src/app/Marina.Web.UI/Login.aspx b/slips/src/app/Marina.Web.UI/Login.aspx new file mode 100644 index 0000000..33cd3b9 --- /dev/null +++ b/slips/src/app/Marina.Web.UI/Login.aspx @@ -0,0 +1,36 @@ +<%@ Page Language="C#" MasterPageFile="~/Site.Master" AutoEventWireup="true" CodeBehind="Login.aspx.cs" Inherits="Marina.Web.UI.Login" Title="Untitled Page" %> +<%@ Import namespace="Marina.Web.Views"%> +<%@ Import namespace="Marina.Presentation.DTO"%> +<%@ Import namespace="Marina.Infrastructure"%> + + + + + + + + + + + + +
user name:
password:
+ +

+ Need to register? +

+ + + +
    + + +
  • <%# Transform.From(Container.DataItem).To().Message %>
  • +
    + +
+ +
+ +
+ diff --git a/slips/src/app/Marina.Web.UI/Login.aspx.cs b/slips/src/app/Marina.Web.UI/Login.aspx.cs new file mode 100644 index 0000000..2ddd0e2 --- /dev/null +++ b/slips/src/app/Marina.Web.UI/Login.aspx.cs @@ -0,0 +1,22 @@ +using System; +using System.Collections.Generic; +using System.Web.UI; +using Marina.Presentation.DTO; +using Marina.Presentation.Presenters; +using Marina.Presentation.Views; + +namespace Marina.Web.UI { + public partial class Login : Page, ILoginView { + protected void Page_Load( object sender, EventArgs e ) { + ILoginPresenter presenter = new LoginPresenter( this ); + uxLoginButton.Click += delegate { presenter.Login( ); }; + } + + public void Display( DisplayResponseLineDTO responseMessage ) { + IList< DisplayResponseLineDTO > messages = new List< DisplayResponseLineDTO >( ); + messages.Add( responseMessage ); + uxResponseMessagesRepeater.DataSource = messages; + uxResponseMessagesRepeater.DataBind( ); + } + } +} \ No newline at end of file diff --git a/slips/src/app/Marina.Web.UI/Login.aspx.designer.cs b/slips/src/app/Marina.Web.UI/Login.aspx.designer.cs new file mode 100644 index 0000000..09d1252 --- /dev/null +++ b/slips/src/app/Marina.Web.UI/Login.aspx.designer.cs @@ -0,0 +1,34 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:2.0.50727.1433 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace Marina.Web.UI { + + + public partial class Login { + + /// + /// uxLoginButton control. + /// + /// + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// + protected global::System.Web.UI.WebControls.Button uxLoginButton; + + /// + /// uxResponseMessagesRepeater control. + /// + /// + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// + protected global::System.Web.UI.WebControls.Repeater uxResponseMessagesRepeater; + } +} diff --git a/slips/src/app/Marina.Web.UI/Marina.Web.UI.csproj b/slips/src/app/Marina.Web.UI/Marina.Web.UI.csproj new file mode 100644 index 0000000..cc8e74f --- /dev/null +++ b/slips/src/app/Marina.Web.UI/Marina.Web.UI.csproj @@ -0,0 +1,215 @@ + + + Debug + AnyCPU + 9.0.21022 + 2.0 + {29824849-3D66-4ACF-8699-79BB60C30BD7} + {349c5851-65df-11da-9384-00065b846f21};{fae04ec0-301f-11d3-bf4b-00c04f79efbc} + Library + Properties + Marina.Web.UI + Marina.Web.UI + v3.5 + + + true + full + false + bin\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\ + TRACE + prompt + 4 + + + + + + 3.5 + + + 3.5 + + + 3.5 + + + 3.5 + + + + + + + + + + + + + + + AvailableSlips.aspx + ASPXCodeBehind + + + AvailableSlips.aspx + + + ContactUs.aspx + ASPXCodeBehind + + + ContactUs.aspx + + + CurrentLeases.aspx + ASPXCodeBehind + + + CurrentLeases.aspx + + + Default.aspx + ASPXCodeBehind + + + Default.aspx + + + DockView.aspx + ASPXCodeBehind + + + DockView.aspx + + + LeaseSlip.aspx + ASPXCodeBehind + + + LeaseSlip.aspx + + + Login.aspx + ASPXCodeBehind + + + Login.aspx + + + RegisterBoat.aspx + ASPXCodeBehind + + + RegisterBoat.aspx + + + Registration.aspx + ASPXCodeBehind + + + Registration.aspx + + + Site.Master + ASPXCodeBehind + + + Site.Master + + + UpdateCustomerRegistration.aspx + ASPXCodeBehind + + + UpdateCustomerRegistration.aspx + + + ViewRegisteredBoats.aspx + ASPXCodeBehind + + + ViewRegisteredBoats.aspx + + + WebServicesAPI.aspx + ASPXCodeBehind + + + WebServicesAPI.aspx + + + + + + + + + + + + + + + + + + + + + + + + + + {F9AF658A-2A26-49DE-A964-7A846A8DCC2A} + Marina + + + + + + + + + Always + + + + + + + + + + + + + False + True + 1400 + / + + + False + False + + + + + \ No newline at end of file diff --git a/slips/src/app/Marina.Web.UI/RegisterBoat.aspx b/slips/src/app/Marina.Web.UI/RegisterBoat.aspx new file mode 100644 index 0000000..9047bef --- /dev/null +++ b/slips/src/app/Marina.Web.UI/RegisterBoat.aspx @@ -0,0 +1,48 @@ +<%@ Page Language="C#" MasterPageFile="~/Site.Master" AutoEventWireup="true" CodeBehind="RegisterBoat.aspx.cs" Inherits="Marina.Web.UI.RegisterBoat" Title="Untitled Page" %> +<%@ Import namespace="Marina.Web.Views"%> + +<%@ Import namespace="Marina.Presentation.DTO"%> +<%@ Import namespace="Marina.Infrastructure"%> + + + +

Register Boat

+ + + +
    + + +
  • <%# Transform.From(Container.DataItem).To().Message %>
  • +
    + +
+ +
+ + + + + + + + + + + + + + + + + + +
registration number:
manufacturer:
model year:
length:
+ + +
+ View All Registered Boats +
+ +
+ diff --git a/slips/src/app/Marina.Web.UI/RegisterBoat.aspx.cs b/slips/src/app/Marina.Web.UI/RegisterBoat.aspx.cs new file mode 100644 index 0000000..5fa7751 --- /dev/null +++ b/slips/src/app/Marina.Web.UI/RegisterBoat.aspx.cs @@ -0,0 +1,20 @@ +using System; +using System.Collections.Generic; +using System.Web.UI; +using Marina.Presentation.DTO; +using Marina.Presentation.Presenters; +using Marina.Presentation.Views; + +namespace Marina.Web.UI { + public partial class RegisterBoat : Page, IRegisterBoatView { + protected void Page_Load( object sender, EventArgs e ) { + IRegisterBoatPresenter presenter = new RegisterBoatPresenter( this ); + uxRegisterBoatButton.Click += delegate { presenter.SubmitRegistration( ); }; + } + + public void Display( IEnumerable< DisplayResponseLineDTO > response ) { + uxResponseRepeater.DataSource = response; + uxResponseRepeater.DataBind( ); + } + } +} \ No newline at end of file diff --git a/slips/src/app/Marina.Web.UI/RegisterBoat.aspx.designer.cs b/slips/src/app/Marina.Web.UI/RegisterBoat.aspx.designer.cs new file mode 100644 index 0000000..a91ce97 --- /dev/null +++ b/slips/src/app/Marina.Web.UI/RegisterBoat.aspx.designer.cs @@ -0,0 +1,34 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:2.0.50727.1433 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace Marina.Web.UI { + + + public partial class RegisterBoat { + + /// + /// uxResponseRepeater control. + /// + /// + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// + protected global::System.Web.UI.WebControls.Repeater uxResponseRepeater; + + /// + /// uxRegisterBoatButton control. + /// + /// + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// + protected global::System.Web.UI.WebControls.Button uxRegisterBoatButton; + } +} diff --git a/slips/src/app/Marina.Web.UI/Registration.aspx b/slips/src/app/Marina.Web.UI/Registration.aspx new file mode 100644 index 0000000..138ebae --- /dev/null +++ b/slips/src/app/Marina.Web.UI/Registration.aspx @@ -0,0 +1,48 @@ +<%@ Page Language="C#" MasterPageFile="~/Site.Master" AutoEventWireup="true" CodeBehind="Registration.aspx.cs" Inherits="Marina.Web.UI.Registration" Title="Untitled Page" EnableViewState="false" %> +<%@ Import namespace="Marina.Presentation.DTO"%> +<%@ Import namespace="Marina.Infrastructure"%> + + + +

Registration

+ + + + + + + + + + + + + + + + + + + + + + + + + + +
username:
password:
first name:
last name:
phone:
city:
+ + + + +
    + + +
  • <%# Transform.From(Container.DataItem).To().Message %>
  • +
    + +
+ +
+
diff --git a/slips/src/app/Marina.Web.UI/Registration.aspx.cs b/slips/src/app/Marina.Web.UI/Registration.aspx.cs new file mode 100644 index 0000000..2418421 --- /dev/null +++ b/slips/src/app/Marina.Web.UI/Registration.aspx.cs @@ -0,0 +1,44 @@ +using System; +using System.Collections.Generic; +using System.Web.UI; +using Marina.Presentation.DTO; +using Marina.Presentation.Presenters; +using Marina.Presentation.Views; + +namespace Marina.Web.UI { + public partial class Registration : Page, ICustomerRegistrationView { + protected void Page_Load( object sender, EventArgs e ) { + ICustomerRegistrationPresenter presenter = new CustomerRegistrationPresenter( this ); + uxRegisterButton.Click += delegate { presenter.RegisterCustomer( ); }; + } + + public string UserName() { + return Request.Params[ "uxUserNameTextBox" ]; + } + + public string Password() { + return Request.Params[ "uxPasswordTextBox" ]; + } + + public string FirstName() { + return Request.Params[ "uxFirstNameTextBox" ]; + } + + public string LastName() { + return Request.Params[ "uxLastNameTextBox" ]; + } + + public string PhoneNumber() { + return Request.Params[ "uxPhoneNumberTextBox" ]; + } + + public string City() { + return Request.Params[ "uxCityTextBox" ]; + } + + public void Display( IEnumerable< DisplayResponseLineDTO > response ) { + uxResponseMessagesRepeater.DataSource = response; + uxResponseMessagesRepeater.DataBind( ); + } + } +} \ No newline at end of file diff --git a/slips/src/app/Marina.Web.UI/Registration.aspx.designer.cs b/slips/src/app/Marina.Web.UI/Registration.aspx.designer.cs new file mode 100644 index 0000000..52ebc4e --- /dev/null +++ b/slips/src/app/Marina.Web.UI/Registration.aspx.designer.cs @@ -0,0 +1,34 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:2.0.50727.1433 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace Marina.Web.UI { + + + public partial class Registration { + + /// + /// uxRegisterButton control. + /// + /// + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// + protected global::System.Web.UI.WebControls.Button uxRegisterButton; + + /// + /// uxResponseMessagesRepeater control. + /// + /// + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// + protected global::System.Web.UI.WebControls.Repeater uxResponseMessagesRepeater; + } +} diff --git a/slips/src/app/Marina.Web.UI/Site.Master b/slips/src/app/Marina.Web.UI/Site.Master new file mode 100644 index 0000000..346b700 --- /dev/null +++ b/slips/src/app/Marina.Web.UI/Site.Master @@ -0,0 +1,89 @@ +<%@ Import namespace="Marina.Web.Views"%> +<%@ Master Language="C#" AutoEventWireup="true" CodeBehind="Site.master.cs" Inherits="Marina.Web.UI.Site" EnableViewState="false" %> + + + + + Inland Marina Ltd + + + + + + +
+ + + +
+ + +
+
+
+

site actions

+
+ +
+ +
+
+

additional information

+
+
+

+ Inland Marina Ltd, is the largest marina on Inland Lake and has the capacity to house 150 boats + with plans to add another dock bringing their total capacity to 200 boats. We are currently concluding + negotiations to purchase a large marina facility in San Diego. +

+
+
+
+
+

Web Services API

+
+ +
+ +
+ +
+
+
+ + +
+
+
+ +
+ + + +
+ + diff --git a/slips/src/app/Marina.Web.UI/Site.Master.cs b/slips/src/app/Marina.Web.UI/Site.Master.cs new file mode 100644 index 0000000..a4ab4dd --- /dev/null +++ b/slips/src/app/Marina.Web.UI/Site.Master.cs @@ -0,0 +1,8 @@ +using System; +using System.Web.UI; + +namespace Marina.Web.UI { + public partial class Site : MasterPage { + protected void Page_Load( object sender, EventArgs e ) {} + } +} \ No newline at end of file diff --git a/slips/src/app/Marina.Web.UI/Site.Master.designer.cs b/slips/src/app/Marina.Web.UI/Site.Master.designer.cs new file mode 100644 index 0000000..7bae518 --- /dev/null +++ b/slips/src/app/Marina.Web.UI/Site.Master.designer.cs @@ -0,0 +1,43 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:2.0.50727.1433 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace Marina.Web.UI { + + + public partial class Site { + + /// + /// ContentPlaceHolder1 control. + /// + /// + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// + protected global::System.Web.UI.WebControls.ContentPlaceHolder ContentPlaceHolder1; + + /// + /// form2 control. + /// + /// + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// + protected global::System.Web.UI.HtmlControls.HtmlForm form2; + + /// + /// ContentPlaceHolder2 control. + /// + /// + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// + protected global::System.Web.UI.WebControls.ContentPlaceHolder ContentPlaceHolder2; + } +} diff --git a/slips/src/app/Marina.Web.UI/UpdateCustomerRegistration.aspx b/slips/src/app/Marina.Web.UI/UpdateCustomerRegistration.aspx new file mode 100644 index 0000000..f84ada1 --- /dev/null +++ b/slips/src/app/Marina.Web.UI/UpdateCustomerRegistration.aspx @@ -0,0 +1,52 @@ +<%@ Page Language="C#" MasterPageFile="~/Site.Master" AutoEventWireup="true" CodeBehind="UpdateCustomerRegistration.aspx.cs" Inherits="Marina.Web.UI.UpdateCustomerRegistration" Title="Untitled Page" %> +<%@ Import namespace="Marina.Web.Views"%> +<%@ Import namespace="System.ComponentModel"%> +<%@ Import namespace="Marina.Infrastructure"%> +<%@ Import namespace="Marina.Presentation.DTO"%> +<%@ Import namespace="Marina.Web.UI"%> + + + + +

Update Registration

+ + + + + + + + + + + + + + + + + + + + + + + + + +
username:
password:
first name:
last name:
phone:
city:
+ + + + +
    + + +
  • <%# Transform.From( Container.DataItem ).To< DisplayResponseLineDTO >( ).Message %>
  • +
    + +
+ +
+ +
\ No newline at end of file diff --git a/slips/src/app/Marina.Web.UI/UpdateCustomerRegistration.aspx.cs b/slips/src/app/Marina.Web.UI/UpdateCustomerRegistration.aspx.cs new file mode 100644 index 0000000..7e4762f --- /dev/null +++ b/slips/src/app/Marina.Web.UI/UpdateCustomerRegistration.aspx.cs @@ -0,0 +1,27 @@ +using System; +using System.Collections.Generic; +using System.Web.UI; +using Marina.Presentation.DTO; +using Marina.Presentation.Presenters; +using Marina.Presentation.Views; + +namespace Marina.Web.UI { + public partial class UpdateCustomerRegistration : Page, IUpdateRegistrationView { + protected void Page_Load( object sender, EventArgs e ) { + UpdateCustomerRegistrationPresenter presenter = new UpdateCustomerRegistrationPresenter( this ); + presenter.Initialize( ); + uxUpdateButton.Click += delegate { presenter.UpdateRegistration( ); }; + } + + public void Display( CustomerRegistrationDisplayDTO customerRegistration ) { + CustomerRegistration = customerRegistration; + } + + public void Display( IEnumerable< DisplayResponseLineDTO > response ) { + uxResponseMessagesRepeater.DataSource = response; + uxResponseMessagesRepeater.DataBind( ); + } + + public CustomerRegistrationDisplayDTO CustomerRegistration; + } +} \ No newline at end of file diff --git a/slips/src/app/Marina.Web.UI/UpdateCustomerRegistration.aspx.designer.cs b/slips/src/app/Marina.Web.UI/UpdateCustomerRegistration.aspx.designer.cs new file mode 100644 index 0000000..8bdaa34 --- /dev/null +++ b/slips/src/app/Marina.Web.UI/UpdateCustomerRegistration.aspx.designer.cs @@ -0,0 +1,34 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:2.0.50727.1433 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace Marina.Web.UI { + + + public partial class UpdateCustomerRegistration { + + /// + /// uxUpdateButton control. + /// + /// + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// + protected global::System.Web.UI.WebControls.Button uxUpdateButton; + + /// + /// uxResponseMessagesRepeater control. + /// + /// + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// + protected global::System.Web.UI.WebControls.Repeater uxResponseMessagesRepeater; + } +} diff --git a/slips/src/app/Marina.Web.UI/ViewRegisteredBoats.aspx b/slips/src/app/Marina.Web.UI/ViewRegisteredBoats.aspx new file mode 100644 index 0000000..70781f4 --- /dev/null +++ b/slips/src/app/Marina.Web.UI/ViewRegisteredBoats.aspx @@ -0,0 +1,34 @@ +<%@ Page Language="C#" MasterPageFile="~/Site.Master" AutoEventWireup="true" CodeBehind="ViewRegisteredBoats.aspx.cs" Inherits="Marina.Web.UI.ViewRegisteredBoats" Title="Untitled Page" EnableViewState="false" %> +<%@ Import namespace="Marina.Presentation.DTO"%> +<%@ Import namespace="Marina.Infrastructure"%> + + + +

Your Registered Boats

+ + + + + + + + + + + + + + + + + + + + + + + +
Registration NumberManufacturerModel YearLength (in feet)
<%# Transform.From(Container.DataItem).To().RegistrationNumber %><%# Transform.From(Container.DataItem).To().Manufacturer %><%# Transform.From(Container.DataItem).To().ModelYear %><%# Transform.From(Container.DataItem).To().Length %>
+ +
+
diff --git a/slips/src/app/Marina.Web.UI/ViewRegisteredBoats.aspx.cs b/slips/src/app/Marina.Web.UI/ViewRegisteredBoats.aspx.cs new file mode 100644 index 0000000..ab9bd77 --- /dev/null +++ b/slips/src/app/Marina.Web.UI/ViewRegisteredBoats.aspx.cs @@ -0,0 +1,19 @@ +using System; +using System.Collections.Generic; +using System.Web.UI; +using Marina.Presentation.DTO; +using Marina.Presentation.Presenters; +using Marina.Presentation.Views; + +namespace Marina.Web.UI { + public partial class ViewRegisteredBoats : Page, IRegisteredBoatsView { + protected void Page_Load( object sender, EventArgs e ) { + new ViewRegisteredBoatsPresenter( this ).Initialize( ); + } + + public void Display( IEnumerable< BoatRegistrationDTO > boats ) { + uxBoatsRepeater.DataSource = boats; + uxBoatsRepeater.DataBind( ); + } + } +} \ No newline at end of file diff --git a/slips/src/app/Marina.Web.UI/ViewRegisteredBoats.aspx.designer.cs b/slips/src/app/Marina.Web.UI/ViewRegisteredBoats.aspx.designer.cs new file mode 100644 index 0000000..1c19862 --- /dev/null +++ b/slips/src/app/Marina.Web.UI/ViewRegisteredBoats.aspx.designer.cs @@ -0,0 +1,25 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:2.0.50727.1433 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace Marina.Web.UI { + + + public partial class ViewRegisteredBoats { + + /// + /// uxBoatsRepeater control. + /// + /// + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// + protected global::System.Web.UI.WebControls.Repeater uxBoatsRepeater; + } +} diff --git a/slips/src/app/Marina.Web.UI/Web.config b/slips/src/app/Marina.Web.UI/Web.config new file mode 100644 index 0000000..290d934 --- /dev/null +++ b/slips/src/app/Marina.Web.UI/Web.config @@ -0,0 +1,95 @@ + + + + + +
+ +
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/slips/src/app/Marina.Web.UI/WebServicesAPI.aspx b/slips/src/app/Marina.Web.UI/WebServicesAPI.aspx new file mode 100644 index 0000000..ff4e738 --- /dev/null +++ b/slips/src/app/Marina.Web.UI/WebServicesAPI.aspx @@ -0,0 +1,15 @@ +<%@ Page Language="C#" MasterPageFile="~/Site.Master" AutoEventWireup="true" CodeBehind="WebServicesAPI.aspx.cs" Inherits="Marina.Web.UI.WebServicesAPI" Title="Untitled Page" %> + + + +

Our Web Services API

+

+ If you're interested in checking out our web services API check out: +

+ +
diff --git a/slips/src/app/Marina.Web.UI/WebServicesAPI.aspx.cs b/slips/src/app/Marina.Web.UI/WebServicesAPI.aspx.cs new file mode 100644 index 0000000..9ffb517 --- /dev/null +++ b/slips/src/app/Marina.Web.UI/WebServicesAPI.aspx.cs @@ -0,0 +1,23 @@ +using System; +using System.Collections; +using System.Configuration; +using System.Data; +using System.Linq; +using System.Web; +using System.Web.Security; +using System.Web.UI; +using System.Web.UI.WebControls; +using System.Web.UI.WebControls.WebParts; +using System.Web.UI.HtmlControls; +using System.Xml.Linq; + +namespace Marina.Web.UI +{ + public partial class WebServicesAPI : System.Web.UI.Page + { + protected void Page_Load(object sender, EventArgs e) + { + + } + } +} diff --git a/slips/src/app/Marina.Web.UI/WebServicesAPI.aspx.designer.cs b/slips/src/app/Marina.Web.UI/WebServicesAPI.aspx.designer.cs new file mode 100644 index 0000000..ffaa12b --- /dev/null +++ b/slips/src/app/Marina.Web.UI/WebServicesAPI.aspx.designer.cs @@ -0,0 +1,16 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:2.0.50727.1433 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace Marina.Web.UI { + + + public partial class WebServicesAPI { + } +} diff --git a/slips/src/app/Marina.Web.UI/images/back.png b/slips/src/app/Marina.Web.UI/images/back.png new file mode 100644 index 0000000..60faea0 Binary files /dev/null and b/slips/src/app/Marina.Web.UI/images/back.png differ diff --git a/slips/src/app/Marina.Web.UI/images/graphic.jpg b/slips/src/app/Marina.Web.UI/images/graphic.jpg new file mode 100644 index 0000000..9d77757 Binary files /dev/null and b/slips/src/app/Marina.Web.UI/images/graphic.jpg differ diff --git a/slips/src/app/Marina.Web.UI/images/link.png b/slips/src/app/Marina.Web.UI/images/link.png new file mode 100644 index 0000000..7fb049c Binary files /dev/null and b/slips/src/app/Marina.Web.UI/images/link.png differ diff --git a/slips/src/app/Marina.Web.UI/images/logo.jpg b/slips/src/app/Marina.Web.UI/images/logo.jpg new file mode 100644 index 0000000..01c1bde Binary files /dev/null and b/slips/src/app/Marina.Web.UI/images/logo.jpg differ diff --git a/slips/src/app/Marina.Web.UI/images/menu.png b/slips/src/app/Marina.Web.UI/images/menu.png new file mode 100644 index 0000000..8efcaad Binary files /dev/null and b/slips/src/app/Marina.Web.UI/images/menu.png differ diff --git a/slips/src/app/Marina.Web.UI/images/menu_hover.png b/slips/src/app/Marina.Web.UI/images/menu_hover.png new file mode 100644 index 0000000..556801d Binary files /dev/null and b/slips/src/app/Marina.Web.UI/images/menu_hover.png differ diff --git a/slips/src/app/Marina.Web.UI/images/sbi_header.png b/slips/src/app/Marina.Web.UI/images/sbi_header.png new file mode 100644 index 0000000..2f59f1d Binary files /dev/null and b/slips/src/app/Marina.Web.UI/images/sbi_header.png differ diff --git a/slips/src/app/Marina.Web.UI/style/colour.css b/slips/src/app/Marina.Web.UI/style/colour.css new file mode 100644 index 0000000..f06194f --- /dev/null +++ b/slips/src/app/Marina.Web.UI/style/colour.css @@ -0,0 +1,85 @@ +html{height: 100%;} + +body +{ background: #837560; + color: #70695A; +} + +blockquote +{ background: #FFFFFF; + color: #70695A; + border-color: #767676; +} + +#main +{ background: #FFFFFF url(../images/back.png) repeat-y; + color: #70695A; +} + +#links, #footer, #menu, #menu li a +{ background: #FFFFFF url(../images/menu.png); + color: #DBD7D1; + border-color: #D7D7D7; +} + +#links a, #footer a, #links a:hover, #footer a:hover +{ background: transparent; + color: #DBD7D1; +} + +#logo +{ background: #FFFFFF url(../images/logo.jpg) no-repeat; + color: #70695A; +} + +#logo h1 +{ background: transparent; + color: #FFFFFF; +} + +h1, #column2 h1 +{ background: transparent; + color: #CE7014; + border-color: #CAAE90; +} + +#menu li a:hover, #menu li a#selected, #menu li a#selected:hover +{ background: #FFFFFF url(../images/menu_hover.png); + color: #70695A; +} + +#content, #column2 a, #column2 a:hover +{ background: transparent; + color: #70695A; +} + +.sidebaritem, .sidebaritem a, .sidebaritem a:hover +{ background: transparent; + color: #DBD7D1; +} + +.sbihead +{ background: #FFFFFF url(../images/sbi_header.png); + color: #70695A; +} + +.sbihead h1 +{ background: transparent; + color: #70695A; +} + +.sbilinks li a +{ background: #FFFFFF url(../images/link.png); + color: #DBD7D1; +} + +.sbilinks li a:hover +{ background: #B7B7B7; + color: #CE7014; +} + +input, textarea +{ background: #FFFFFF; + color: #70695A; + border-color: #CAAE90; +} diff --git a/slips/src/app/Marina.Web.UI/style/style.css b/slips/src/app/Marina.Web.UI/style/style.css new file mode 100644 index 0000000..89a1c21 --- /dev/null +++ b/slips/src/app/Marina.Web.UI/style/style.css @@ -0,0 +1,274 @@ +/* global */ +html{height: 100%;} + +body +{ font-family: verdana, arial, sans-serif; + padding: 0px; + margin: 0px; + font-size: .68em; +} + +p +{ margin: 0px; + padding: 0px 0px 16px 0px; + line-height: 1.7em; +} + +h1 +{ font-family: arial, sans-serif; + letter-spacing: .1em; +} + +h2 +{ margin: 0px; + padding: 0px 0px 4px 0px; + font-size: 100%; +} + +img{border: 0px;} + +a{outline: none;} + +/* image positioning - left, right and center */ +.left +{ float: left; + padding: 0px 8px 0px 0px; +} + +.right +{ float: right; + padding: 0px 0px 0px 8px; +} + +.center +{ display: block; + text-align: center; + margin: 0 auto; +} + +/* block quote */ +blockquote +{ margin: 20px 0px 20px 0px; + padding: 10px 20px 0px 20px; + border-left: 8px solid; +} + +/* unordered list */ +ul +{ margin: 8px 0px 0px 16px; + padding: 0px; +} + +ul li +{ list-style-type: square; + margin: 0px 0px 11px 0px; + padding: 0px; +} + +/* ordered list */ +ol +{ margin: 8px 0px 0px 24px; + padding: 0px; +} + +ol li +{ margin: 0px 0px 11px 0px; + padding: 0px; +} + +/* main container */ +#main +{ width: 780px; + margin-left: auto; + margin-right: auto; +} + +/* links above the logo / footer */ +#links, #footer +{ margin-left: auto; + margin-right: auto; + padding: 10px 21px 0px 19px; + width: 720px; + height: 26px; + font-size: 94%; + text-transform: uppercase; +} + +#links{text-align: right;} + +#footer{text-align: center;} + +#links a, #footer a{text-decoration: none;} + +#links a:hover, #footer a:hover{text-decoration: underline;} + +/* logo */ +#logo +{ margin-left: auto; + margin-right: auto; + width: 760px; + height: 100px; + text-align: left; +} + +#logo h1 +{ margin: 0px; + padding: 41px 0px 0px 19px; + font-size: 150%; + letter-spacing: .2em; +} + +/* navigation menu */ +#menu +{ height: 42px; + width: 760px; + margin-left: auto; + margin-right: auto; +} + +#menu ul{margin: 0px auto;} + +#menu li +{ float: left; + margin: 0px; + padding: 0px; +} + +#menu li a +{ display: block; + float: left; + height: 37px; + text-decoration: none; + padding: 3px 19px 2px 19px; + text-transform: uppercase; +} + +/* main content */ +#content +{ margin-left: auto; + margin-right: auto; + width: 760px; + height: auto; + padding: 0px; + overflow: hidden; +} + +/* column 1 - contains sidebar items */ +#column1 +{ width: 207px; + float: right; + padding: 16px 0px 15px 0px; +} + +.sidebaritem +{ text-align: left; + width: 188px; + float: left; + margin: 0px 0px 25px 0px; +} + +.sbihead +{ height: 14px; + width: 188px; + padding: 5px 0px 5px 19px; + text-transform: uppercase; +} + +.sbihead h1 +{ padding: 0px; + margin: 0px; + font-weight: bold; + font-size: 112%; +} + +.sbicontent{padding: 14px 8px 8px 19px;} + +.sbicontent p +{ line-height: 14px; + padding: 0px 0px 8px 0px; +} + +.sbilinks{padding: 0px;} + +.sbilinks ul{margin: 0px auto;} + +.sbilinks li +{ margin: 0px; + float: left; + list-style: none; +} + +.sbilinks li a , .sbilinks li a:hover +{ float: left; + height: 16px; + text-decoration: none; + padding: 5px 0px 4px 19px; + width: 188px; + border: 0px; +} + +/* column 2 - page content */ +#column2 +{ text-align: justify; + width: 512px; + float: left; + padding: 12px 3px 15px 19px; +} + +#column2 h1 +{ padding: 6px 0px 4px 0px; + margin: 0px 0px 12px 0px; + border-bottom: 1px solid; + font-size: 150%; + text-transform: uppercase; + font-weight: normal; +} + +.sidebaritem a, #column2 a, .sidebaritem a:hover, #column2 a:hover +{ padding: 0px 0px 2px 0px; + text-decoration: none; + border-bottom: 1px dashed; +} + +.sidebaritem a:hover, #column2 a:hover{border-bottom: 1px solid;} + +/* contact page - form layout */ +form{margin-top: 0px;} + +div.row +{ clear: both; + width: 448px; +} + +div.row span.formlabel +{ float: left; + width: 150px; + text-align: left; +} + +div.row span.forminput +{ float: right; + text-align: right; +} + +div.spacer +{ clear: both; + width: 80px; +} + +input, textarea +{ width: 259px; + font-family: verdana, arial, sans-serif; + border: 1px solid; + font-size: 100%; + margin: 2px; +} + +.submit +{ font-family: verdana, arial, sans-serif; + border: 1px solid; + width: 70px; + height: 22px; + cursor: pointer; + font-size: 100%; +} diff --git a/slips/src/app/Marina.Web.UI/windsor.config.xml b/slips/src/app/Marina.Web.UI/windsor.config.xml new file mode 100644 index 0000000..7dd706c --- /dev/null +++ b/slips/src/app/Marina.Web.UI/windsor.config.xml @@ -0,0 +1,116 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/slips/src/app/Marina/DataAccess/Builders/DatabaseDelete.cs b/slips/src/app/Marina/DataAccess/Builders/DatabaseDelete.cs new file mode 100644 index 0000000..801aba0 --- /dev/null +++ b/slips/src/app/Marina/DataAccess/Builders/DatabaseDelete.cs @@ -0,0 +1,31 @@ +using System.Collections.Generic; + +namespace Marina.DataAccess.Builders { + public static class DatabaseDelete { + public static IQuery Where< T >( DatabaseColumn column, T equalsValue ) { + return new DeleteQueryBuilder< T >( column, equalsValue ).Build( ); + } + + private class DeleteQueryBuilder< T > : IDeleteQueryBuilder { + public DeleteQueryBuilder( DatabaseColumn column, T value ) { + _column = column; + _value = value; + } + + public override string ToString() { + return string.Format( "DELETE FROM [{0}] WHERE [{0}].[{1}] = @{1};", _column.TableName, _column.ColumnName ); + } + + public IEnumerable< DatabaseCommandParameter > Parameters() { + yield return new DatabaseCommandParameter( _column.ColumnName, _value ); + } + + public IQuery Build() { + return new Query( this ); + } + + private readonly DatabaseColumn _column; + private readonly T _value; + } + } +} \ No newline at end of file diff --git a/slips/src/app/Marina/DataAccess/Builders/DatabaseInsert.cs b/slips/src/app/Marina/DataAccess/Builders/DatabaseInsert.cs new file mode 100644 index 0000000..57c0c1d --- /dev/null +++ b/slips/src/app/Marina/DataAccess/Builders/DatabaseInsert.cs @@ -0,0 +1,50 @@ +using System.Collections.Generic; +using System.Text; + +namespace Marina.DataAccess.Builders { + public static class DatabaseInsert { + public static IInsertQueryBuilder Into( string tableName ) { + return new InsertQueryBuilder( tableName ); + } + + private class InsertQueryBuilder : IInsertQueryBuilder { + public InsertQueryBuilder( string tableName ) { + _tableName = tableName; + _parameters = new List< DatabaseCommandParameter >( ); + } + + public IEnumerable< DatabaseCommandParameter > Parameters() { + return _parameters; + } + + public IQuery Build() { + return new Query( this ); + } + + public IInsertQueryBuilder AddValue< T >( DatabaseColumn column, T value ) { + _parameters.Add( new DatabaseCommandParameter( column.ColumnName, value ) ); + return this; + } + + public override string ToString() { + StringBuilder builder = new StringBuilder( ); + builder.AppendFormat( "INSERT INTO {0} ({1}) VALUES ({2});SELECT @@IDENTITY;", _tableName, + GetParameterNames( string.Empty ), + GetParameterNames( "@" ) ); + return builder.ToString( ); + } + + private string GetParameterNames( string prefix ) { + StringBuilder builder = new StringBuilder( ); + foreach ( DatabaseCommandParameter parameter in _parameters ) { + builder.AppendFormat( "{0}{1},", prefix, parameter.ColumnName ); + } + builder.Remove( builder.Length - 1, 1 ); + return builder.ToString( ); + } + + private readonly string _tableName; + private readonly IList< DatabaseCommandParameter > _parameters; + } + } +} \ No newline at end of file diff --git a/slips/src/app/Marina/DataAccess/Builders/DatabaseSelect.cs b/slips/src/app/Marina/DataAccess/Builders/DatabaseSelect.cs new file mode 100644 index 0000000..6e61fff --- /dev/null +++ b/slips/src/app/Marina/DataAccess/Builders/DatabaseSelect.cs @@ -0,0 +1,101 @@ +using System.Collections.Generic; +using System.Text; + +namespace Marina.DataAccess.Builders { + public static class DatabaseSelect { + public static ISelectQueryBuilder From( string tableName ) { + return new SelectQueryBuilder( tableName ); + } + + private class SelectQueryBuilder : ISelectQueryBuilder { + public SelectQueryBuilder( string tableName ) { + _tableName = string.Format( "[{0}]", tableName ); + _innerJoins = new List< InnerJoin >( ); + _selectColumns = new List< DatabaseColumn >( ); + } + + public ISelectQueryBuilder AddColumn( DatabaseColumn column ) { + _selectColumns.Add( column ); + return this; + } + + public ISelectQueryBuilder InnerJoinOn( DatabaseColumn leftColumn, DatabaseColumn rightColumn ) { + _innerJoins.Add( new InnerJoin( leftColumn, rightColumn ) ); + return this; + } + + public ISelectQueryBuilder Where( DatabaseColumn column, string value ) { + _whereClause = new WhereClause( column, value ); + return this; + } + + public ISelectQueryBuilder Where< T >( DatabaseColumn column, T value ) { + return Where( column, value.ToString( ) ); + } + + public override string ToString() { + return + string.Format( "SELECT {0} FROM {1} {2} {3};", GetColumnNames( ), _tableName, GetInnerJoins( ), _whereClause ); + } + + public IEnumerable< DatabaseCommandParameter > Parameters() { + foreach ( DatabaseColumn databaseColumn in _selectColumns ) { + yield return new DatabaseCommandParameter( databaseColumn.ColumnName, string.Empty ); + } + } + + public IQuery Build() { + return new Query( this ); + } + + private string GetInnerJoins() { + StringBuilder builder = new StringBuilder( ); + foreach ( InnerJoin innerJoin in _innerJoins ) { + builder.Append( innerJoin.ToString( ) ); + } + return builder.ToString( ); + } + + private string GetColumnNames() { + StringBuilder builder = new StringBuilder( ); + foreach ( DatabaseColumn selectColumn in _selectColumns ) { + builder.AppendFormat( "{0},", selectColumn ); + } + builder.Remove( builder.Length - 1, 1 ); + return builder.ToString( ); + } + + private readonly string _tableName; + private readonly IList< DatabaseColumn > _selectColumns; + private readonly IList< InnerJoin > _innerJoins; + private WhereClause _whereClause; + + private class InnerJoin : IJoin { + public InnerJoin( DatabaseColumn leftColumn, DatabaseColumn rightColumn ) { + _leftColumn = leftColumn; + _rightColumn = rightColumn; + } + + public DatabaseColumn Left() { + return _leftColumn; + } + + public DatabaseColumn Right() { + return _rightColumn; + } + + public override string ToString() { + return + string.Format( "INNER JOIN [{0}] ON [{0}].[{1}] = [{2}].[{3}]", + _leftColumn.TableName, + _leftColumn.ColumnName, + _rightColumn.TableName, + _rightColumn.ColumnName ); + } + + private readonly DatabaseColumn _leftColumn; + private readonly DatabaseColumn _rightColumn; + } + } + } +} \ No newline at end of file diff --git a/slips/src/app/Marina/DataAccess/Builders/DatabaseUpdate.cs b/slips/src/app/Marina/DataAccess/Builders/DatabaseUpdate.cs new file mode 100644 index 0000000..8b90edc --- /dev/null +++ b/slips/src/app/Marina/DataAccess/Builders/DatabaseUpdate.cs @@ -0,0 +1,52 @@ +using System.Collections.Generic; +using System.Text; + +namespace Marina.DataAccess.Builders { + public static class DatabaseUpdate { + public static IUpdateQueryBuilder Where< T >( DatabaseColumn whereColumn, T whereValue ) { + return new UpdateQueryBuilder( whereColumn, whereValue.ToString( ) ); + } + + private class UpdateQueryBuilder : IUpdateQueryBuilder { + public UpdateQueryBuilder( DatabaseColumn whereColumn, string whereValue ) + : this( new List< DatabaseCommandParameter >( ), new WhereClause( whereColumn, whereValue ) ) {} + + public UpdateQueryBuilder( IList< DatabaseCommandParameter > parameters, WhereClause where ) { + _parameters = parameters; + _where = where; + } + + public IEnumerable< DatabaseCommandParameter > Parameters() { + return _parameters; + } + + public IQuery Build() { + return new Query( this ); + } + + public IUpdateQueryBuilder Add( DatabaseColumn column, string value ) { + _parameters.Add( new DatabaseCommandParameter( column.ColumnName, value ) ); + return this; + } + + public override string ToString() { + StringBuilder builder = new StringBuilder( ); + builder.AppendFormat( "UPDATE [{0}] SET {1};", _where.Column( ).TableName, GetParameterNames( ) ); + return builder.ToString( ); + } + + private string GetParameterNames() { + StringBuilder builder = new StringBuilder( ); + foreach ( DatabaseCommandParameter parameter in _parameters ) { + builder.AppendFormat( "[{0}].[{1}] = @{1},", _where.Column( ).TableName, parameter.ColumnName ); + } + builder.Remove( builder.Length - 1, 1 ); + builder.Append( _where ); + return builder.ToString( ); + } + + private readonly IList< DatabaseCommandParameter > _parameters; + private readonly WhereClause _where; + } + } +} \ No newline at end of file diff --git a/slips/src/app/Marina/DataAccess/Builders/IDeleteQueryBuilder.cs b/slips/src/app/Marina/DataAccess/Builders/IDeleteQueryBuilder.cs new file mode 100644 index 0000000..2b7290a --- /dev/null +++ b/slips/src/app/Marina/DataAccess/Builders/IDeleteQueryBuilder.cs @@ -0,0 +1,3 @@ +namespace Marina.DataAccess.Builders { + public interface IDeleteQueryBuilder : IQueryBuilder {} +} \ No newline at end of file diff --git a/slips/src/app/Marina/DataAccess/Builders/IInsertQueryBuilder.cs b/slips/src/app/Marina/DataAccess/Builders/IInsertQueryBuilder.cs new file mode 100644 index 0000000..946c914 --- /dev/null +++ b/slips/src/app/Marina/DataAccess/Builders/IInsertQueryBuilder.cs @@ -0,0 +1,5 @@ +namespace Marina.DataAccess.Builders { + public interface IInsertQueryBuilder : IQueryBuilder { + IInsertQueryBuilder AddValue< T >( DatabaseColumn column, T value ); + } +} \ No newline at end of file diff --git a/slips/src/app/Marina/DataAccess/Builders/IJoin.cs b/slips/src/app/Marina/DataAccess/Builders/IJoin.cs new file mode 100644 index 0000000..c4ae46f --- /dev/null +++ b/slips/src/app/Marina/DataAccess/Builders/IJoin.cs @@ -0,0 +1,6 @@ +namespace Marina.DataAccess.Builders { + internal interface IJoin { + DatabaseColumn Left(); + DatabaseColumn Right(); + } +} \ No newline at end of file diff --git a/slips/src/app/Marina/DataAccess/Builders/IQuery.cs b/slips/src/app/Marina/DataAccess/Builders/IQuery.cs new file mode 100644 index 0000000..a45527f --- /dev/null +++ b/slips/src/app/Marina/DataAccess/Builders/IQuery.cs @@ -0,0 +1,7 @@ +using System.Data; + +namespace Marina.DataAccess.Builders { + public interface IQuery { + void Prepare( IDbCommand command ); + } +} \ No newline at end of file diff --git a/slips/src/app/Marina/DataAccess/Builders/IQueryBuilder.cs b/slips/src/app/Marina/DataAccess/Builders/IQueryBuilder.cs new file mode 100644 index 0000000..175c2d5 --- /dev/null +++ b/slips/src/app/Marina/DataAccess/Builders/IQueryBuilder.cs @@ -0,0 +1,9 @@ +using System.Collections.Generic; + +namespace Marina.DataAccess.Builders { + public interface IQueryBuilder { + IEnumerable< DatabaseCommandParameter > Parameters(); + + IQuery Build(); + } +} \ No newline at end of file diff --git a/slips/src/app/Marina/DataAccess/Builders/ISelectQueryBuilder.cs b/slips/src/app/Marina/DataAccess/Builders/ISelectQueryBuilder.cs new file mode 100644 index 0000000..058a7a1 --- /dev/null +++ b/slips/src/app/Marina/DataAccess/Builders/ISelectQueryBuilder.cs @@ -0,0 +1,11 @@ +namespace Marina.DataAccess.Builders { + public interface ISelectQueryBuilder : IQueryBuilder { + ISelectQueryBuilder AddColumn( DatabaseColumn column ); + + ISelectQueryBuilder InnerJoinOn( DatabaseColumn leftColumn, DatabaseColumn rightColumn ); + + ISelectQueryBuilder Where( DatabaseColumn column, string value ); + + ISelectQueryBuilder Where< T >( DatabaseColumn column, T value ); + } +} \ No newline at end of file diff --git a/slips/src/app/Marina/DataAccess/Builders/IUpdateQueryBuilder.cs b/slips/src/app/Marina/DataAccess/Builders/IUpdateQueryBuilder.cs new file mode 100644 index 0000000..c599243 --- /dev/null +++ b/slips/src/app/Marina/DataAccess/Builders/IUpdateQueryBuilder.cs @@ -0,0 +1,5 @@ +namespace Marina.DataAccess.Builders { + public interface IUpdateQueryBuilder : IQueryBuilder { + IUpdateQueryBuilder Add( DatabaseColumn column, string value ); + } +} \ No newline at end of file diff --git a/slips/src/app/Marina/DataAccess/Builders/Query.cs b/slips/src/app/Marina/DataAccess/Builders/Query.cs new file mode 100644 index 0000000..0b95bf1 --- /dev/null +++ b/slips/src/app/Marina/DataAccess/Builders/Query.cs @@ -0,0 +1,22 @@ +using System.Data; + +namespace Marina.DataAccess.Builders { + public class Query : IQuery { + public Query( IQueryBuilder builder ) { + _builder = builder; + } + + public void Prepare( IDbCommand command ) { + command.CommandText = _builder.ToString( ); + command.CommandType = CommandType.Text; + foreach ( DatabaseCommandParameter parameter in _builder.Parameters( ) ) { + IDataParameter commandParameter = command.CreateParameter( ); + commandParameter.ParameterName = "@" + parameter.ColumnName; + commandParameter.Value = parameter.Value; + command.Parameters.Add( commandParameter ); + } + } + + private readonly IQueryBuilder _builder; + } +} \ No newline at end of file diff --git a/slips/src/app/Marina/DataAccess/Builders/SqlQuery.cs b/slips/src/app/Marina/DataAccess/Builders/SqlQuery.cs new file mode 100644 index 0000000..c6b2b47 --- /dev/null +++ b/slips/src/app/Marina/DataAccess/Builders/SqlQuery.cs @@ -0,0 +1,18 @@ +using System.Data; + +namespace Marina.DataAccess.Builders { + public class SqlQuery : IQuery { + public SqlQuery( string sqlQuery ) { + _sqlQuery = sqlQuery; + } + + public void Prepare( IDbCommand command ) { + if ( command != null ) { + command.CommandText = _sqlQuery; + command.CommandType = CommandType.Text; + } + } + + private readonly string _sqlQuery; + } +} \ No newline at end of file diff --git a/slips/src/app/Marina/DataAccess/Builders/WhereClause.cs b/slips/src/app/Marina/DataAccess/Builders/WhereClause.cs new file mode 100644 index 0000000..5768fde --- /dev/null +++ b/slips/src/app/Marina/DataAccess/Builders/WhereClause.cs @@ -0,0 +1,27 @@ +namespace Marina.DataAccess.Builders { + public class WhereClause { + public WhereClause( DatabaseColumn column, string value ) { + _column = column; + _value = value; + } + + public DatabaseColumn Column() { + return _column; + } + + public string Value() { + return _value; + } + + public string ToSql() { + return ToString( ); + } + + public override string ToString() { + return string.Format( " WHERE [{0}].[{1}] = {2};", _column.TableName, _column.ColumnName, _value ); + } + + private readonly DatabaseColumn _column; + private readonly string _value; + } +} \ No newline at end of file diff --git a/slips/src/app/Marina/DataAccess/DataMappers/BoatDataMapper.cs b/slips/src/app/Marina/DataAccess/DataMappers/BoatDataMapper.cs new file mode 100644 index 0000000..fbd33cd --- /dev/null +++ b/slips/src/app/Marina/DataAccess/DataMappers/BoatDataMapper.cs @@ -0,0 +1,74 @@ +using System; +using System.Collections.Generic; +using Marina.DataAccess.Builders; +using Marina.DataAccess.Schemas; +using Marina.Domain; +using Marina.Domain.Interfaces; +using Marina.Infrastructure.Container; + +namespace Marina.DataAccess.DataMappers { + public class BoatDataMapper : IBoatDataMapper { + public BoatDataMapper() : this( Resolve.DependencyFor< IDatabaseGateway >( ) ) {} + + public BoatDataMapper( IDatabaseGateway gateway ) { + _gateway = gateway; + } + + public IEnumerable< IBoat > AllBoatsFor( long customerId ) { + return Map.From( _gateway.FindAllRowsMatching( Queries.SelectBoatsFor( customerId ) ) ); + } + + public void Insert( IEnumerable< IBoat > boats, long forCustomerId ) { + _gateway.Execute( Queries.InsertQueriesFor( boats, forCustomerId ) ); + } + + public void Update( IEnumerable< IBoat > boats, long forCustomerId ) { + using ( IDatabaseTransaction transaction = new DatabaseTransaction( ) ) { + _gateway.Execute( DatabaseDelete.Where( BoatTable.CustomerID, forCustomerId ) ); + Insert( boats, forCustomerId ); + transaction.Commit( ); + } + } + + private readonly IDatabaseGateway _gateway; + + private class Queries { + public static IQuery SelectBoatsFor( long customerId ) { + return DatabaseSelect.From( BoatTable.TableName ) + .AddColumn( BoatTable.Length ) + .AddColumn( BoatTable.Manufacturer ) + .AddColumn( BoatTable.ModelYear ) + .AddColumn( BoatTable.RegistrationNumber ) + .AddColumn( BoatTable.BoatID ) + .Where( BoatTable.CustomerID, customerId.ToString( ) ).Build( ); + } + + public static IEnumerable< IQuery > InsertQueriesFor( IEnumerable< IBoat > boats, long customerId ) { + foreach ( IBoat boat in boats ) { + yield return DatabaseInsert.Into( BoatTable.TableName ) + .AddValue( BoatTable.CustomerID, customerId ) + .AddValue( BoatTable.Length, boat.LengthInFeet( ) ) + .AddValue( BoatTable.Manufacturer, boat.Manufacturer( ) ) + .AddValue( BoatTable.ModelYear, boat.YearOfModel( ).Year ) + .AddValue( BoatTable.RegistrationNumber, boat.RegistrationNumber( ) ).Build( ); + } + } + } + + private class Map { + public static IEnumerable< IBoat > From( IEnumerable< IDatabaseRow > rows ) { + foreach ( IDatabaseRow dataRow in rows ) { + yield return new Boat( + dataRow.From< long >( BoatTable.BoatID ), + dataRow.From< string >( BoatTable.RegistrationNumber ), + dataRow.From< string >( BoatTable.Manufacturer ), + dataRow.From< int >( BoatTable.ModelYear ) != 0 + ? new DateTime( dataRow.From< int >( BoatTable.ModelYear ), 1, 01 ) + : DateTime.MinValue, + dataRow.From< long >( BoatTable.Length ) + ); + } + } + } + } +} \ No newline at end of file diff --git a/slips/src/app/Marina/DataAccess/DataMappers/CustomerDataMapper.cs b/slips/src/app/Marina/DataAccess/DataMappers/CustomerDataMapper.cs new file mode 100644 index 0000000..cdc56be --- /dev/null +++ b/slips/src/app/Marina/DataAccess/DataMappers/CustomerDataMapper.cs @@ -0,0 +1,82 @@ +using Marina.DataAccess.Builders; +using Marina.DataAccess.Schemas; +using Marina.Domain; +using Marina.Domain.Interfaces; +using Marina.Infrastructure.Container; + +namespace Marina.DataAccess.DataMappers { + public class CustomerDataMapper : ICustomerDataMapper { + public CustomerDataMapper() : this + ( + Resolve.DependencyFor< IDatabaseGateway >( ), + Resolve.DependencyFor< IBoatDataMapper >( ), + Resolve.DependencyFor< ILeaseDataMapper >( ), + Resolve.DependencyFor< IRegistrationDataMapper >( ) + ) {} + + public CustomerDataMapper( IDatabaseGateway gateway, IBoatDataMapper boatMapper, ILeaseDataMapper leaseMapper, + IRegistrationDataMapper registrationMapper ) { + _gateway = gateway; + _boatMapper = boatMapper; + _leaseMapper = leaseMapper; + _registrationMapper = registrationMapper; + } + + public ICustomer FindBy( long customerId ) { + if ( customerId > 0 ) { + return new Customer( customerId, + _boatMapper.AllBoatsFor( customerId ), + _leaseMapper.AllLeasesFor( customerId ), + _registrationMapper.For( customerId ) ); + } + return null; + } + + public ICustomer FindBy( string username ) { + IDatabaseRow row = _gateway.LoadRowUsing( Queries.SelectCustomerBy( username ) ); + return FindBy( row.From< long >( AuthorizationTable.CustomerID ) ); + } + + public void Insert( ICustomer customer ) { + using ( IDatabaseTransaction workUnit = new DatabaseTransaction( ) ) { + customer.ChangeIdTo( _gateway.ExecuteScalar( Queries.Insert( ) ) ); + _registrationMapper.Insert( customer.Registration( ), customer.ID( ) ); + _boatMapper.Insert( customer.RegisteredBoats( ), customer.ID( ) ); + _leaseMapper.Insert( customer.Leases( ), customer.ID( ) ); + workUnit.Commit( ); + } + } + + public void Update( ICustomer customer ) { + using ( IDatabaseTransaction workUnit = new DatabaseTransaction( ) ) { + _registrationMapper.Update( customer.Registration( ), customer.ID( ) ); + _boatMapper.Update( customer.RegisteredBoats( ), customer.ID( ) ); + _leaseMapper.Update( customer.Leases( ), customer.ID( ) ); + workUnit.Commit( ); + } + } + + private readonly IDatabaseGateway _gateway; + private readonly IBoatDataMapper _boatMapper; + private readonly ILeaseDataMapper _leaseMapper; + private readonly IRegistrationDataMapper _registrationMapper; + + private static class Queries { + public static IQuery Insert() { + return DatabaseInsert.Into( CustomerTable.TableName ) + .AddValue( CustomerTable.FirstName, string.Empty ) + .AddValue( CustomerTable.LastName, string.Empty ) + .AddValue( CustomerTable.Phone, string.Empty ) + .AddValue( CustomerTable.City, string.Empty ).Build( ); + } + + public static IQuery SelectCustomerBy( string username ) { + return DatabaseSelect.From( AuthorizationTable.TableName ) + .AddColumn( AuthorizationTable.CustomerID ) + .AddColumn( AuthorizationTable.UserName ) + .Where( AuthorizationTable.UserName, "'" + username + "'" ) + .Build( ); + } + } + } +} \ No newline at end of file diff --git a/slips/src/app/Marina/DataAccess/DataMappers/DockDataMapper.cs b/slips/src/app/Marina/DataAccess/DataMappers/DockDataMapper.cs new file mode 100644 index 0000000..bf2ae13 --- /dev/null +++ b/slips/src/app/Marina/DataAccess/DataMappers/DockDataMapper.cs @@ -0,0 +1,54 @@ +using Marina.DataAccess.Builders; +using Marina.DataAccess.Schemas; +using Marina.Domain; +using Marina.Domain.Interfaces; +using Marina.Infrastructure.Container; + +namespace Marina.DataAccess.DataMappers { + public class DockDataMapper : IDockDataMapper { + public DockDataMapper() : this( Resolve.DependencyFor< IDatabaseGateway >( ) ) {} + + public DockDataMapper( IDatabaseGateway gateway ) { + _gateway = gateway; + } + + public IDock FindBy( long dockId ) { + return Map.From( _gateway.LoadRowUsing( Queries.SelectDockBy( dockId ) ) ); + } + + private readonly IDatabaseGateway _gateway; + + private static class Queries { + public static IQuery SelectDockBy( long dockId ) { + return DatabaseSelect + .From( DockTable.TableName ) + .AddColumn( DockTable.DockID ) + .AddColumn( DockTable.DockName ) + .AddColumn( DockTable.LocationId ) + .AddColumn( DockTable.WaterService ) + .AddColumn( DockTable.ElectricalService ) + .AddColumn( LocationTable.Name ) + .InnerJoinOn( LocationTable.ID, DockTable.LocationId ) + .Where( DockTable.DockID, dockId ).Build( ); + } + } + + private class Map { + public static IDock From( IDatabaseRow row ) { + return new Dock( + row.From< long >( DockTable.DockID ), + row.From< string >( DockTable.DockName ), + new Location( row.From< string >( LocationTable.Name ) ), + GetEnabledUtilities( row ) + ); + } + + private static IUtility GetEnabledUtilities( IDatabaseRow row ) { + return Utilities.For( + row.From< bool >( DockTable.WaterService ) ? Utilities.Water : null, + row.From< bool >( DockTable.ElectricalService ) ? Utilities.Electrical : null + ); + } + } + } +} \ No newline at end of file diff --git a/slips/src/app/Marina/DataAccess/DataMappers/IBoatDataMapper.cs b/slips/src/app/Marina/DataAccess/DataMappers/IBoatDataMapper.cs new file mode 100644 index 0000000..bcdb7d1 --- /dev/null +++ b/slips/src/app/Marina/DataAccess/DataMappers/IBoatDataMapper.cs @@ -0,0 +1,12 @@ +using System.Collections.Generic; +using Marina.Domain.Interfaces; + +namespace Marina.DataAccess.DataMappers { + public interface IBoatDataMapper { + IEnumerable< IBoat > AllBoatsFor( long customerId ); + + void Insert( IEnumerable< IBoat > boats, long forCustomerId ); + + void Update( IEnumerable< IBoat > boats, long forCustomerId ); + } +} \ No newline at end of file diff --git a/slips/src/app/Marina/DataAccess/DataMappers/ICustomerDataMapper.cs b/slips/src/app/Marina/DataAccess/DataMappers/ICustomerDataMapper.cs new file mode 100644 index 0000000..fc757e7 --- /dev/null +++ b/slips/src/app/Marina/DataAccess/DataMappers/ICustomerDataMapper.cs @@ -0,0 +1,11 @@ +using Marina.Domain.Interfaces; + +namespace Marina.DataAccess.DataMappers { + public interface ICustomerDataMapper : IDataMapper< ICustomer > { + void Insert( ICustomer customer ); + + void Update( ICustomer customer ); + + ICustomer FindBy( string username ); + } +} \ No newline at end of file diff --git a/slips/src/app/Marina/DataAccess/DataMappers/IDataMapper.cs b/slips/src/app/Marina/DataAccess/DataMappers/IDataMapper.cs new file mode 100644 index 0000000..249eeb7 --- /dev/null +++ b/slips/src/app/Marina/DataAccess/DataMappers/IDataMapper.cs @@ -0,0 +1,5 @@ +namespace Marina.DataAccess.DataMappers { + public interface IDataMapper< T > { + T FindBy( long id ); + } +} \ No newline at end of file diff --git a/slips/src/app/Marina/DataAccess/DataMappers/IDockDataMapper.cs b/slips/src/app/Marina/DataAccess/DataMappers/IDockDataMapper.cs new file mode 100644 index 0000000..5140eb1 --- /dev/null +++ b/slips/src/app/Marina/DataAccess/DataMappers/IDockDataMapper.cs @@ -0,0 +1,6 @@ +using Marina.DataAccess.DataMappers; +using Marina.Domain.Interfaces; + +namespace Marina.DataAccess.DataMappers { + public interface IDockDataMapper : IDataMapper< IDock > {} +} \ No newline at end of file diff --git a/slips/src/app/Marina/DataAccess/DataMappers/ILeaseDataMapper.cs b/slips/src/app/Marina/DataAccess/DataMappers/ILeaseDataMapper.cs new file mode 100644 index 0000000..c7134d7 --- /dev/null +++ b/slips/src/app/Marina/DataAccess/DataMappers/ILeaseDataMapper.cs @@ -0,0 +1,14 @@ +using System.Collections.Generic; +using Marina.Domain.Interfaces; + +namespace Marina.DataAccess.DataMappers { + public interface ILeaseDataMapper { + IEnumerable< ISlipLease > AllLeasesFor( long customerId ); + + void Insert( IEnumerable< ISlipLease > leases, long forCustomerId ); + + void Update( IEnumerable< ISlipLease > leases, long forCustomerId ); + + bool IsLeased( long slipId ); + } +} \ No newline at end of file diff --git a/slips/src/app/Marina/DataAccess/DataMappers/IRegistrationDataMapper.cs b/slips/src/app/Marina/DataAccess/DataMappers/IRegistrationDataMapper.cs new file mode 100644 index 0000000..a9f01dc --- /dev/null +++ b/slips/src/app/Marina/DataAccess/DataMappers/IRegistrationDataMapper.cs @@ -0,0 +1,11 @@ +using Marina.Domain.Interfaces; + +namespace Marina.DataAccess.DataMappers { + public interface IRegistrationDataMapper { + IRegistration For( long customerId ); + + void Insert( IRegistration registration, long forCustomerId ); + + void Update( IRegistration registration, long forCustomerId ); + } +} \ No newline at end of file diff --git a/slips/src/app/Marina/DataAccess/DataMappers/ISlipDataMapper.cs b/slips/src/app/Marina/DataAccess/DataMappers/ISlipDataMapper.cs new file mode 100644 index 0000000..99ff069 --- /dev/null +++ b/slips/src/app/Marina/DataAccess/DataMappers/ISlipDataMapper.cs @@ -0,0 +1,9 @@ +using Marina.DataAccess.DataMappers; +using Marina.Domain.Interfaces; +using Marina.Infrastructure; + +namespace Marina.DataAccess.DataMappers { + public interface ISlipDataMapper : IDataMapper< ISlip > { + IRichEnumerable< ISlip > AllSlips(); + } +} \ No newline at end of file diff --git a/slips/src/app/Marina/DataAccess/DataMappers/LeaseDataMapper.cs b/slips/src/app/Marina/DataAccess/DataMappers/LeaseDataMapper.cs new file mode 100644 index 0000000..8214b05 --- /dev/null +++ b/slips/src/app/Marina/DataAccess/DataMappers/LeaseDataMapper.cs @@ -0,0 +1,87 @@ +using System; +using System.Collections.Generic; +using Marina.DataAccess.Builders; +using Marina.DataAccess.Schemas; +using Marina.Domain; +using Marina.Domain.Interfaces; +using Marina.Infrastructure.Container; + +namespace Marina.DataAccess.DataMappers { + public class LeaseDataMapper : ILeaseDataMapper { + public LeaseDataMapper() + : this( Resolve.DependencyFor< IDatabaseGateway >( ), Resolve.DependencyFor< ISlipDataMapper >( ) ) {} + + public LeaseDataMapper( IDatabaseGateway gateway, ISlipDataMapper slipMapper ) { + _gateway = gateway; + _slipMapper = slipMapper; + } + + public IEnumerable< ISlipLease > AllLeasesFor( long customerId ) { + foreach ( IDatabaseRow row in _gateway.FindAllRowsMatching( Queries.SelectLeasesFor( customerId ) ) ) { + yield return + new SlipLease( + _slipMapper.FindBy( row.From< long >( LeaseTable.SlipID ) ), + LeaseDurations.FindFor( row.From< DateTime >( LeaseTable.StartDate ), row.From< DateTime >( LeaseTable.EndDate ) ), + row.From< DateTime >( LeaseTable.StartDate ), + row.From< DateTime >( LeaseTable.EndDate ) + ); + } + } + + public void Insert( IEnumerable< ISlipLease > leases, long forCustomerId ) { + using ( IDatabaseTransaction transaction = new DatabaseTransaction( ) ) { + IList< IQuery > queries = new List< IQuery >( ); + foreach ( ISlipLease lease in leases ) { + queries.Add( + DatabaseInsert.Into( LeaseTable.TableName ) + .AddValue( LeaseTable.StartDate, lease.StartDate( ) ) + .AddValue( LeaseTable.EndDate, lease.ExpiryDate( ) ) + .AddValue( LeaseTable.SlipID, lease.Slip( ).ID( ) ) + .AddValue( LeaseTable.CustomerID, forCustomerId ) + .AddValue( LeaseTable.LeaseTypeID, lease.Duration( ).ID( ) ).Build( ) + ); + } + _gateway.Execute( queries ); + transaction.Commit( ); + } + } + + public void Update( IEnumerable< ISlipLease > leases, long forCustomerId ) { + using ( IDatabaseTransaction transaction = new DatabaseTransaction( ) ) { + _gateway.Execute( DatabaseDelete.Where( LeaseTable.CustomerID, forCustomerId ) ); + Insert( leases, forCustomerId ); + transaction.Commit( ); + } + } + + public bool IsLeased( long slipId ) { + IQuery query = + DatabaseSelect.From( LeaseTable.TableName ).AddColumn( LeaseTable.SlipID ).Where( LeaseTable.SlipID, slipId ).Build( ); + + return !_gateway.LoadRowUsing( query ).Equals( DatabaseRow.Blank ); + } + + private readonly IDatabaseGateway _gateway; + private readonly ISlipDataMapper _slipMapper; + + private static class Queries { + public static IQuery SelectLeasesFor( long customerId ) { + return DatabaseSelect + .From( LeaseTable.TableName ) + .AddColumn( LeaseTable.EndDate ) + .AddColumn( LeaseTable.ID ) + .AddColumn( LeaseTable.LeaseTypeID ) + .AddColumn( LeaseTable.SlipID ) + .AddColumn( LeaseTable.StartDate ) + .Where( LeaseTable.CustomerID, customerId ).Build( ); + } + + public static IQuery SelectLeaseFor( long slipId ) { + return DatabaseSelect.From( LeaseTable.TableName ) + .AddColumn( LeaseTable.StartDate ) + .AddColumn( LeaseTable.EndDate ) + .Where( LeaseTable.SlipID, slipId ).Build( ); + } + } + } +} \ No newline at end of file diff --git a/slips/src/app/Marina/DataAccess/DataMappers/RegistrationDataMapper.cs b/slips/src/app/Marina/DataAccess/DataMappers/RegistrationDataMapper.cs new file mode 100644 index 0000000..5c2cd41 --- /dev/null +++ b/slips/src/app/Marina/DataAccess/DataMappers/RegistrationDataMapper.cs @@ -0,0 +1,88 @@ +using Marina.DataAccess.Builders; +using Marina.DataAccess.Schemas; +using Marina.Domain; +using Marina.Domain.Interfaces; +using Marina.Infrastructure.Container; + +namespace Marina.DataAccess.DataMappers { + public class RegistrationDataMapper : IRegistrationDataMapper { + public RegistrationDataMapper() : this( Resolve.DependencyFor< IDatabaseGateway >( ) ) {} + + public RegistrationDataMapper( IDatabaseGateway gateway ) { + _gateway = gateway; + } + + public IRegistration For( long customerId ) { + return Mappers.From( _gateway.LoadRowUsing( Queries.SelectRegistrationFor( customerId ) ) ); + } + + public void Insert( IRegistration registration, long forCustomerId ) { + using ( IDatabaseTransaction unitOfWork = new DatabaseTransaction( ) ) { + _gateway.Execute( Queries.Insert( registration, forCustomerId ), + Queries.UpdateCustomer( registration, forCustomerId ) ); + unitOfWork.Commit( ); + } + } + + public void Update( IRegistration registration, long forCustomerId ) { + using ( IDatabaseTransaction unitOfWork = new DatabaseTransaction( ) ) { + _gateway.Execute( Queries.UpdateCustomer( registration, forCustomerId ), + Queries.UpdateAuthorization( registration, forCustomerId ) ); + unitOfWork.Commit( ); + } + } + + private readonly IDatabaseGateway _gateway; + + private class Queries { + public static IQuery SelectRegistrationFor( long customerId ) { + return DatabaseSelect.From( CustomerTable.TableName ) + .AddColumn( CustomerTable.FirstName ) + .AddColumn( CustomerTable.LastName ) + .AddColumn( CustomerTable.Phone ) + .AddColumn( CustomerTable.City ) + .AddColumn( AuthorizationTable.UserName ) + .AddColumn( AuthorizationTable.Password ) + .InnerJoinOn( AuthorizationTable.CustomerID, CustomerTable.CustomerID ) + .Where( CustomerTable.CustomerID, customerId.ToString( ) ).Build( ); + } + + public static IQuery Insert( IRegistration registration, long forCustomerId ) { + return DatabaseInsert.Into( AuthorizationTable.TableName ) + .AddValue( AuthorizationTable.CustomerID, forCustomerId.ToString( ) ) + .AddValue( AuthorizationTable.UserName, registration.Username( ) ) + .AddValue( AuthorizationTable.Password, registration.Password( ) ) + .Build( ); + } + + public static IQuery UpdateCustomer( IRegistration registration, long forCustomerId ) { + return DatabaseUpdate.Where( CustomerTable.CustomerID, forCustomerId ) + .Add( CustomerTable.FirstName, registration.FirstName( ) ) + .Add( CustomerTable.LastName, registration.LastName( ) ) + .Add( CustomerTable.Phone, registration.PhoneNumber( ) ) + .Add( CustomerTable.City, registration.City( ) ) + .Build( ); + } + + public static IQuery UpdateAuthorization( IRegistration registration, long forCustomerId ) { + return DatabaseUpdate.Where( AuthorizationTable.CustomerID, forCustomerId ) + .Add( AuthorizationTable.UserName, registration.Username( ) ) + .Add( AuthorizationTable.Password, registration.Password( ) ) + .Build( ); + } + } + + private class Mappers { + public static IRegistration From( IDatabaseRow row ) { + return new CustomerRegistration( + row.From< string >( AuthorizationTable.UserName ), + row.From< string >( AuthorizationTable.Password ), + row.From< string >( CustomerTable.FirstName ), + row.From< string >( CustomerTable.LastName ), + row.From< string >( CustomerTable.Phone ), + row.From< string >( CustomerTable.City ) + ); + } + } + } +} \ No newline at end of file diff --git a/slips/src/app/Marina/DataAccess/DataMappers/SlipDataMapper.cs b/slips/src/app/Marina/DataAccess/DataMappers/SlipDataMapper.cs new file mode 100644 index 0000000..67f7d69 --- /dev/null +++ b/slips/src/app/Marina/DataAccess/DataMappers/SlipDataMapper.cs @@ -0,0 +1,97 @@ +using System.Collections.Generic; +using Marina.DataAccess.Builders; +using Marina.DataAccess.Schemas; +using Marina.Domain; +using Marina.Domain.Interfaces; +using Marina.Infrastructure; +using Marina.Infrastructure.Container; + +namespace Marina.DataAccess.DataMappers { + public class SlipDataMapper : ISlipDataMapper { + public SlipDataMapper( IDatabaseGateway gateway ) { + _gateway = gateway; + } + + public ISlip FindBy( long slipId ) { + return Map.From( _gateway.LoadRowUsing( Queries.SelectSlipBy( slipId ) ) ); + } + + public IRichEnumerable< ISlip > AllSlips() { + return new RichEnumerable< ISlip >( FetchAllSlips( ) ); + } + + private IEnumerable< ISlip > FetchAllSlips() { + return Map.From( _gateway.FindAllRowsMatching( Queries.SelectAllSlips( ) ) ); + } + + private readonly IDatabaseGateway _gateway; + + private static class Queries { + public static IQuery SelectAllSlips() { + return SelectAllColumns( ).Build( ); + } + + public static IQuery SelectSlipBy( long slipId ) { + return SelectAllColumns( ).Where( SlipTable.ID, slipId ).Build( ); + } + + private static ISelectQueryBuilder SelectAllColumns() { + return DatabaseSelect + .From( SlipTable.TableName ) + .AddColumn( SlipTable.ID ) + .AddColumn( SlipTable.Width ) + .AddColumn( SlipTable.Length ) + .AddColumn( SlipTable.DockID ) + .AddColumn( DockTable.DockName ) + .AddColumn( DockTable.WaterService ) + .AddColumn( DockTable.ElectricalService ) + .AddColumn( LocationTable.Name ) + .InnerJoinOn( DockTable.DockID, SlipTable.DockID ) + .InnerJoinOn( LocationTable.ID, DockTable.LocationId ); + } + } + + private static class Map { + public static IEnumerable< ISlip > From( IEnumerable< IDatabaseRow > rows ) { + return new EnumerableMapper< IDatabaseRow, ISlip >( new DatabaseRowToSlipMapper( ) ).MapFrom( rows ); + } + + public static ISlip From( IDatabaseRow row ) { + return new DatabaseRowToSlipMapper( ).MapFrom( row ); + } + + private class DatabaseRowToSlipMapper : IMapper< IDatabaseRow, ISlip > { + public DatabaseRowToSlipMapper() + : this( Resolve.DependencyFor< ILeaseDataMapper >( ) ) {} + + public DatabaseRowToSlipMapper( ILeaseDataMapper leaseDataMapper ) { + this.leaseDataMapper = leaseDataMapper; + } + + public ISlip MapFrom( IDatabaseRow row ) { + return new Slip( + row.From< long >( SlipTable.ID ), + CreateDockFrom( row ), + row.From< int >( SlipTable.Width ), + row.From< int >( SlipTable.Length ), + leaseDataMapper.IsLeased( row.From< long >( SlipTable.ID ) ) + ); + } + + private static Dock CreateDockFrom( IDatabaseRow row ) { + return new Dock( + row.From< long >( DockTable.DockID ), + row.From< string >( DockTable.DockName ), + new Location( row.From< string >( LocationTable.Name ) ), + Utilities.For( + row.From< bool >( DockTable.WaterService ) ? Utilities.Water : null, + row.From< bool >( DockTable.ElectricalService ) ? Utilities.Electrical : null + ) + ); + } + + private readonly ILeaseDataMapper leaseDataMapper; + } + } + } +} \ No newline at end of file diff --git a/slips/src/app/Marina/DataAccess/DatabaseColumn.cs b/slips/src/app/Marina/DataAccess/DatabaseColumn.cs new file mode 100644 index 0000000..cc79200 --- /dev/null +++ b/slips/src/app/Marina/DataAccess/DatabaseColumn.cs @@ -0,0 +1,23 @@ +namespace Marina.DataAccess { + public class DatabaseColumn { + internal DatabaseColumn( string tableName, string columnName ) { + _tableName = tableName; + _columnName = columnName; + } + + public string TableName { + get { return _tableName; } + } + + public string ColumnName { + get { return _columnName; } + } + + public override string ToString() { + return string.Format( "[{0}].[{1}]", _tableName, _columnName ); + } + + private readonly string _tableName; + private readonly string _columnName; + } +} \ No newline at end of file diff --git a/slips/src/app/Marina/DataAccess/DatabaseCommand.cs b/slips/src/app/Marina/DataAccess/DatabaseCommand.cs new file mode 100644 index 0000000..f394ec0 --- /dev/null +++ b/slips/src/app/Marina/DataAccess/DatabaseCommand.cs @@ -0,0 +1,23 @@ +using System; +using System.Data; + +namespace Marina.DataAccess { + public class DatabaseCommand : IDatabaseCommand { + public DatabaseCommand( IDbCommand command ) { + _command = command; + } + + public DataTable ExecuteQuery() { + DataTable table = new DataTable( ); + table.Load( _command.ExecuteReader( ) ); + return table; + } + + public long ExecuteScalarQuery() { + object scalar = _command.ExecuteScalar( ); + return DBNull.Value != scalar ? Convert.ToInt32( scalar ) : -1; + } + + private readonly IDbCommand _command; + } +} \ No newline at end of file diff --git a/slips/src/app/Marina/DataAccess/DatabaseCommandParameter.cs b/slips/src/app/Marina/DataAccess/DatabaseCommandParameter.cs new file mode 100644 index 0000000..84a0675 --- /dev/null +++ b/slips/src/app/Marina/DataAccess/DatabaseCommandParameter.cs @@ -0,0 +1,19 @@ +namespace Marina.DataAccess { + public class DatabaseCommandParameter { + public DatabaseCommandParameter( string columnName, object value ) { + _columnName = columnName; + _value = value; + } + + public string ColumnName { + get { return _columnName; } + } + + public object Value { + get { return _value; } + } + + private readonly string _columnName; + private readonly object _value; + } +} \ No newline at end of file diff --git a/slips/src/app/Marina/DataAccess/DatabaseConfiguration.cs b/slips/src/app/Marina/DataAccess/DatabaseConfiguration.cs new file mode 100644 index 0000000..f70a437 --- /dev/null +++ b/slips/src/app/Marina/DataAccess/DatabaseConfiguration.cs @@ -0,0 +1,22 @@ +using System.Configuration; + +namespace Marina.DataAccess { + public class DatabaseConfiguration : IDatabaseConfiguration { + private readonly ConnectionStringSettings _connectionSettings; + + public DatabaseConfiguration() + : this( ConfigurationManager.ConnectionStrings[ ConfigurationManager.AppSettings[ "ActiveConnection" ] ] ) {} + + public DatabaseConfiguration( ConnectionStringSettings connectionSettings ) { + _connectionSettings = connectionSettings; + } + + public string ConnectionString() { + return _connectionSettings.ConnectionString; + } + + public string ProviderName() { + return _connectionSettings.ProviderName; + } + } +} \ No newline at end of file diff --git a/slips/src/app/Marina/DataAccess/DatabaseConnection.cs b/slips/src/app/Marina/DataAccess/DatabaseConnection.cs new file mode 100644 index 0000000..b08399f --- /dev/null +++ b/slips/src/app/Marina/DataAccess/DatabaseConnection.cs @@ -0,0 +1,38 @@ +using System; +using System.Data; +using Marina.DataAccess.Builders; + +namespace Marina.DataAccess { + public class DatabaseConnection : IDatabaseConnection { + private readonly IDbConnection _connection; + + public DatabaseConnection() : this( new DatabaseConfiguration( ), new DatabaseProviderFactory( ) ) {} + + public DatabaseConnection( IDatabaseConfiguration configuration, IDatabaseProviderFactory providerFactory ) { + _connection = providerFactory.CreateConnectionFor( configuration.ProviderName( ) ); + _connection.ConnectionString = configuration.ConnectionString( ); + _connection.Open( ); + } + + public IDatabaseCommand CreateCommandFor( string sqlQuery ) { + return CreateCommandFor( new SqlQuery( sqlQuery ) ); + } + + public IDatabaseCommand CreateCommandFor( IQuery query ) { + IDbCommand command = _connection.CreateCommand( ); + query.Prepare( command ); + return new DatabaseCommand( command ); + } + + public void Dispose() { + Dispose( true ); + GC.SuppressFinalize( this ); + } + + protected virtual void Dispose( bool disposing ) { + if ( disposing ) { + _connection.Close( ); + } + } + } +} \ No newline at end of file diff --git a/slips/src/app/Marina/DataAccess/DatabaseConnectionFactory.cs b/slips/src/app/Marina/DataAccess/DatabaseConnectionFactory.cs new file mode 100644 index 0000000..2747148 --- /dev/null +++ b/slips/src/app/Marina/DataAccess/DatabaseConnectionFactory.cs @@ -0,0 +1,7 @@ +namespace Marina.DataAccess { + public class DatabaseConnectionFactory : IDatabaseConnectionFactory { + public IDatabaseConnection Create() { + return new DatabaseConnection( ); + } + } +} \ No newline at end of file diff --git a/slips/src/app/Marina/DataAccess/DatabaseGateway.cs b/slips/src/app/Marina/DataAccess/DatabaseGateway.cs new file mode 100644 index 0000000..92892f1 --- /dev/null +++ b/slips/src/app/Marina/DataAccess/DatabaseGateway.cs @@ -0,0 +1,60 @@ +using System.Collections.Generic; +using System.Data; +using Marina.DataAccess.Builders; +using Marina.Infrastructure; +using Marina.Infrastructure.Container; + +namespace Marina.DataAccess { + public class DatabaseGateway : IDatabaseGateway { + private readonly IDatabaseConnectionFactory _connectionFactory; + + public DatabaseGateway() : this( Resolve.DependencyFor< IDatabaseConnectionFactory >( ) ) {} + + public DatabaseGateway( IDatabaseConnectionFactory connectionFactory ) { + _connectionFactory = connectionFactory; + } + + public DataTable LoadTableUsing( string sqlQuery ) { + using ( IDatabaseConnection connection = _connectionFactory.Create( ) ) { + IDatabaseCommand command = connection.CreateCommandFor( sqlQuery ); + return ( null != command ) ? command.ExecuteQuery( ) : null; + } + } + + public IEnumerable< IDatabaseRow > FindAllRowsMatching( IQuery query ) { + using ( IDatabaseConnection connection = _connectionFactory.Create( ) ) { + DataTable table = connection.CreateCommandFor( query ).ExecuteQuery( ); + if ( null != table ) { + foreach ( DataRow row in table.Rows ) { + yield return new DatabaseRow( row ); + } + } + } + } + + public void Execute( params IQuery[] queries ) { + Execute( ListFactory.From( queries ) ); + } + + public void Execute( IEnumerable< IQuery > queries ) { + using ( IDatabaseConnection connection = _connectionFactory.Create( ) ) { + foreach ( IQuery query in queries ) { + connection.CreateCommandFor( query ).ExecuteQuery( ); + } + } + } + + public long ExecuteScalar( IQuery query ) { + using ( IDatabaseConnection connection = _connectionFactory.Create( ) ) { + return connection.CreateCommandFor( query ).ExecuteScalarQuery( ); + } + } + + public IDatabaseRow LoadRowUsing( IQuery query ) { + using ( IDatabaseConnection connection = _connectionFactory.Create( ) ) { + DataTable table = connection.CreateCommandFor( query ).ExecuteQuery( ); + return table.Rows.Count > 0 ? new DatabaseRow( table.Rows[ 0 ] ) : DatabaseRow.Blank; + } + } + } +} \ No newline at end of file diff --git a/slips/src/app/Marina/DataAccess/DatabaseProviderFactory.cs b/slips/src/app/Marina/DataAccess/DatabaseProviderFactory.cs new file mode 100644 index 0000000..f93d964 --- /dev/null +++ b/slips/src/app/Marina/DataAccess/DatabaseProviderFactory.cs @@ -0,0 +1,10 @@ +using System.Data; +using System.Data.Common; + +namespace Marina.DataAccess { + public class DatabaseProviderFactory : IDatabaseProviderFactory { + public IDbConnection CreateConnectionFor( string providerName ) { + return DbProviderFactories.GetFactory( providerName ).CreateConnection( ); + } + } +} \ No newline at end of file diff --git a/slips/src/app/Marina/DataAccess/DatabaseRow.cs b/slips/src/app/Marina/DataAccess/DatabaseRow.cs new file mode 100644 index 0000000..53d0b45 --- /dev/null +++ b/slips/src/app/Marina/DataAccess/DatabaseRow.cs @@ -0,0 +1,24 @@ +using System; +using System.Data; + +namespace Marina.DataAccess { + public class DatabaseRow : IDatabaseRow { + public DatabaseRow( DataRow row ) { + _row = row; + } + + public static readonly IDatabaseRow Blank = new BlankDatabaseRow( ); + + public T From< T >( DatabaseColumn column ) { + return ( T )Convert.ChangeType( _row[ column.ColumnName ], typeof( T ) ); + } + + private readonly DataRow _row; + + public class BlankDatabaseRow : IDatabaseRow { + public T From< T >( DatabaseColumn column ) { + return default( T ); + } + } + } +} \ No newline at end of file diff --git a/slips/src/app/Marina/DataAccess/DatabaseTransaction.cs b/slips/src/app/Marina/DataAccess/DatabaseTransaction.cs new file mode 100644 index 0000000..78d87cf --- /dev/null +++ b/slips/src/app/Marina/DataAccess/DatabaseTransaction.cs @@ -0,0 +1,19 @@ +using System.Transactions; + +namespace Marina.DataAccess { + internal class DatabaseTransaction : IDatabaseTransaction { + public DatabaseTransaction() { + _scope = new TransactionScope( ); + } + + public void Commit() { + _scope.Complete( ); + } + + public void Dispose() { + _scope.Dispose( ); + } + + private readonly TransactionScope _scope; + } +} \ No newline at end of file diff --git a/slips/src/app/Marina/DataAccess/Exceptions/ObjectAlreadyAddedToIdentityMapException.cs b/slips/src/app/Marina/DataAccess/Exceptions/ObjectAlreadyAddedToIdentityMapException.cs new file mode 100644 index 0000000..a2cf8c9 --- /dev/null +++ b/slips/src/app/Marina/DataAccess/Exceptions/ObjectAlreadyAddedToIdentityMapException.cs @@ -0,0 +1,9 @@ +using System; +using Marina.Domain.Interfaces; + +namespace Marina.DataAccess.Exceptions { + public class ObjectAlreadyAddedToIdentityMapException : Exception { + public ObjectAlreadyAddedToIdentityMapException( IDomainObject domainObject ) + : base( "With ID Of: " + domainObject.ID( ) ) {} + } +} \ No newline at end of file diff --git a/slips/src/app/Marina/DataAccess/IDatabaseCommand.cs b/slips/src/app/Marina/DataAccess/IDatabaseCommand.cs new file mode 100644 index 0000000..ef6fbd4 --- /dev/null +++ b/slips/src/app/Marina/DataAccess/IDatabaseCommand.cs @@ -0,0 +1,9 @@ +using System.Data; + +namespace Marina.DataAccess { + public interface IDatabaseCommand { + DataTable ExecuteQuery(); + + long ExecuteScalarQuery(); + } +} \ No newline at end of file diff --git a/slips/src/app/Marina/DataAccess/IDatabaseConfiguration.cs b/slips/src/app/Marina/DataAccess/IDatabaseConfiguration.cs new file mode 100644 index 0000000..2fb0637 --- /dev/null +++ b/slips/src/app/Marina/DataAccess/IDatabaseConfiguration.cs @@ -0,0 +1,7 @@ +namespace Marina.DataAccess { + public interface IDatabaseConfiguration { + string ConnectionString(); + + string ProviderName(); + } +} \ No newline at end of file diff --git a/slips/src/app/Marina/DataAccess/IDatabaseConnection.cs b/slips/src/app/Marina/DataAccess/IDatabaseConnection.cs new file mode 100644 index 0000000..2316741 --- /dev/null +++ b/slips/src/app/Marina/DataAccess/IDatabaseConnection.cs @@ -0,0 +1,10 @@ +using System; +using Marina.DataAccess.Builders; + +namespace Marina.DataAccess { + public interface IDatabaseConnection : IDisposable { + IDatabaseCommand CreateCommandFor( string sqlQuery ); + + IDatabaseCommand CreateCommandFor( IQuery query ); + } +} \ No newline at end of file diff --git a/slips/src/app/Marina/DataAccess/IDatabaseConnectionFactory.cs b/slips/src/app/Marina/DataAccess/IDatabaseConnectionFactory.cs new file mode 100644 index 0000000..4672c9a --- /dev/null +++ b/slips/src/app/Marina/DataAccess/IDatabaseConnectionFactory.cs @@ -0,0 +1,5 @@ +namespace Marina.DataAccess { + public interface IDatabaseConnectionFactory { + IDatabaseConnection Create(); + } +} \ No newline at end of file diff --git a/slips/src/app/Marina/DataAccess/IDatabaseGateway.cs b/slips/src/app/Marina/DataAccess/IDatabaseGateway.cs new file mode 100644 index 0000000..f52ea21 --- /dev/null +++ b/slips/src/app/Marina/DataAccess/IDatabaseGateway.cs @@ -0,0 +1,19 @@ +using System.Collections.Generic; +using System.Data; +using Marina.DataAccess.Builders; + +namespace Marina.DataAccess { + public interface IDatabaseGateway { + DataTable LoadTableUsing( string sqlQuery ); + + IEnumerable< IDatabaseRow > FindAllRowsMatching( IQuery query ); + + void Execute( params IQuery[] queries ); + + void Execute( IEnumerable< IQuery > queries ); + + long ExecuteScalar( IQuery query ); + + IDatabaseRow LoadRowUsing( IQuery query ); + } +} \ No newline at end of file diff --git a/slips/src/app/Marina/DataAccess/IDatabaseProviderFactory.cs b/slips/src/app/Marina/DataAccess/IDatabaseProviderFactory.cs new file mode 100644 index 0000000..2fbb6b8 --- /dev/null +++ b/slips/src/app/Marina/DataAccess/IDatabaseProviderFactory.cs @@ -0,0 +1,7 @@ +using System.Data; + +namespace Marina.DataAccess { + public interface IDatabaseProviderFactory { + IDbConnection CreateConnectionFor( string providerName ); + } +} \ No newline at end of file diff --git a/slips/src/app/Marina/DataAccess/IDatabaseRow.cs b/slips/src/app/Marina/DataAccess/IDatabaseRow.cs new file mode 100644 index 0000000..baa07ee --- /dev/null +++ b/slips/src/app/Marina/DataAccess/IDatabaseRow.cs @@ -0,0 +1,5 @@ +namespace Marina.DataAccess { + public interface IDatabaseRow { + T From< T >( DatabaseColumn column ); + } +} \ No newline at end of file diff --git a/slips/src/app/Marina/DataAccess/IDatabaseTransaction.cs b/slips/src/app/Marina/DataAccess/IDatabaseTransaction.cs new file mode 100644 index 0000000..22d83a6 --- /dev/null +++ b/slips/src/app/Marina/DataAccess/IDatabaseTransaction.cs @@ -0,0 +1,7 @@ +using System; + +namespace Marina.DataAccess { + internal interface IDatabaseTransaction : IDisposable { + void Commit(); + } +} \ No newline at end of file diff --git a/slips/src/app/Marina/DataAccess/IIdentityMap.cs b/slips/src/app/Marina/DataAccess/IIdentityMap.cs new file mode 100644 index 0000000..28ad56e --- /dev/null +++ b/slips/src/app/Marina/DataAccess/IIdentityMap.cs @@ -0,0 +1,9 @@ +namespace Marina.DataAccess { + public interface IIdentityMap< T > { + void Add( T domainObject ); + + bool ContainsObjectWithIdOf( long idOfObjectToFind ); + + T FindObjectWithIdOf( long idOfObjectToFind ); + } +} \ No newline at end of file diff --git a/slips/src/app/Marina/DataAccess/IdentityMap.cs b/slips/src/app/Marina/DataAccess/IdentityMap.cs new file mode 100644 index 0000000..c251379 --- /dev/null +++ b/slips/src/app/Marina/DataAccess/IdentityMap.cs @@ -0,0 +1,42 @@ +using System.Collections.Generic; +using Marina.DataAccess.Exceptions; +using Marina.Domain.Interfaces; + +namespace Marina.DataAccess { + public class IdentityMap< T > : IIdentityMap< T > where T : IDomainObject { + public IdentityMap() { + _items = new List< T >( ); + } + + public void Add( T domainObject ) { + EnsureObjectHasNotAlreadyBeenAdded( domainObject ); + _items.Add( domainObject ); + } + + public bool ContainsObjectWithIdOf( long idOfObjectToFind ) { + foreach ( T item in _items ) { + if ( item.ID( ).Equals( idOfObjectToFind ) ) { + return true; + } + } + return false; + } + + public T FindObjectWithIdOf( long idOfObjectToFind ) { + foreach ( T item in _items ) { + if ( item.ID( ).Equals( idOfObjectToFind ) ) { + return item; + } + } + return default( T ); + } + + private void EnsureObjectHasNotAlreadyBeenAdded( T domainObject ) { + if ( ContainsObjectWithIdOf( domainObject.ID( ) ) ) { + throw new ObjectAlreadyAddedToIdentityMapException( domainObject ); + } + } + + private readonly IList< T > _items; + } +} \ No newline at end of file diff --git a/slips/src/app/Marina/DataAccess/Repositories/CustomerRepository.cs b/slips/src/app/Marina/DataAccess/Repositories/CustomerRepository.cs new file mode 100644 index 0000000..ade3e83 --- /dev/null +++ b/slips/src/app/Marina/DataAccess/Repositories/CustomerRepository.cs @@ -0,0 +1,51 @@ +using Marina.DataAccess.DataMappers; +using Marina.Domain; +using Marina.Domain.Interfaces; +using Marina.Domain.Repositories; +using Marina.Infrastructure.Container; + +namespace Marina.DataAccess.Repositories { + public class CustomerRepository : ICustomerRepository { + public CustomerRepository() + : this( new IdentityMap< ICustomer >( ), Resolve.DependencyFor< ICustomerDataMapper >( ) ) {} + + public CustomerRepository( IIdentityMap< ICustomer > identityMap, ICustomerDataMapper mapper ) { + _identityMap = identityMap; + _mapper = mapper; + } + + public ICustomer FindBy( long customerId ) { + if ( _identityMap.ContainsObjectWithIdOf( customerId ) ) { + return _identityMap.FindObjectWithIdOf( customerId ); + } + return FindCustomerBy( customerId ); + } + + public ICustomer FindBy( string username ) { + return _mapper.FindBy( username ); + } + + public void Save( ICustomer customer ) { + if ( _identityMap.ContainsObjectWithIdOf( customer.ID( ) ) ) { + _mapper.Update( customer ); + } + else { + _mapper.Insert( customer ); + _identityMap.Add( customer ); + } + } + + public ICustomer NewCustomer() { + return new Customer( ); + } + + private ICustomer FindCustomerBy( long customerId ) { + ICustomer customer = _mapper.FindBy( customerId ); + _identityMap.Add( customer ); + return customer; + } + + private readonly IIdentityMap< ICustomer > _identityMap; + private readonly ICustomerDataMapper _mapper; + } +} \ No newline at end of file diff --git a/slips/src/app/Marina/DataAccess/Repositories/DockRepository.cs b/slips/src/app/Marina/DataAccess/Repositories/DockRepository.cs new file mode 100644 index 0000000..747ebc2 --- /dev/null +++ b/slips/src/app/Marina/DataAccess/Repositories/DockRepository.cs @@ -0,0 +1,20 @@ +using Marina.DataAccess.DataMappers; +using Marina.Domain.Interfaces; +using Marina.Domain.Repositories; +using Marina.Infrastructure.Container; + +namespace Marina.DataAccess.Repositories { + public class DockRepository : IDockRepository { + public DockRepository() : this( Resolve.DependencyFor< IDockDataMapper >( ) ) {} + + public DockRepository( IDockDataMapper mapper ) { + this.mapper = mapper; + } + + public IDock FindBy( long dockId ) { + return mapper.FindBy( dockId ); + } + + private readonly IDockDataMapper mapper; + } +} \ No newline at end of file diff --git a/slips/src/app/Marina/DataAccess/Repositories/SlipsRepository.cs b/slips/src/app/Marina/DataAccess/Repositories/SlipsRepository.cs new file mode 100644 index 0000000..c6f0b3a --- /dev/null +++ b/slips/src/app/Marina/DataAccess/Repositories/SlipsRepository.cs @@ -0,0 +1,58 @@ +using System.Collections.Generic; +using Marina.DataAccess.DataMappers; +using Marina.Domain.Interfaces; +using Marina.Domain.Repositories; +using Marina.Infrastructure; +using Marina.Infrastructure.Container; + +namespace Marina.DataAccess.Repositories { + public class SlipsRepository : ISlipsRepository { + public SlipsRepository() : this( Resolve.DependencyFor< ISlipDataMapper >( ) ) {} + + public SlipsRepository( ISlipDataMapper mapper ) { + this.mapper = mapper; + } + + public IEnumerable< ISlip > AllAvailableSlips() { + return mapper.AllSlips( ).Where( Is.NotLeased( ) ); + } + + public IEnumerable< ISlip > AllAvailableSlipsFor( IDock dock ) { + return mapper.AllSlips( ).Where( Is.NotLeased( ).And( Is.OnDock( dock ) ) ); + } + + public ISlip FindBy( long slipId ) { + return mapper.FindBy( slipId ); + } + + private readonly ISlipDataMapper mapper; + + private static class Is { + public static ISpecificationBuilder< ISlip > NotLeased() { + return new SpecificationBuilder< ISlip >( new IsNotLeased( ) ); + } + + public static ISpecificationBuilder< ISlip > OnDock( IDock dock ) { + return new SpecificationBuilder< ISlip >( new OnDockSpecification( dock ) ); + } + + private class IsNotLeased : ISpecification< ISlip > { + public bool IsSatisfiedBy( ISlip slip ) { + return !slip.IsLeased( ); + } + } + + private class OnDockSpecification : ISpecification< ISlip > { + private readonly IDock _dock; + + public OnDockSpecification( IDock dock ) { + _dock = dock; + } + + public bool IsSatisfiedBy( ISlip item ) { + return _dock.ID( ).Equals( item.Dock( ).ID( ) ); + } + } + } + } +} \ No newline at end of file diff --git a/slips/src/app/Marina/DataAccess/Schemas/AuthorizationTable.cs b/slips/src/app/Marina/DataAccess/Schemas/AuthorizationTable.cs new file mode 100644 index 0000000..73be973 --- /dev/null +++ b/slips/src/app/Marina/DataAccess/Schemas/AuthorizationTable.cs @@ -0,0 +1,9 @@ +namespace Marina.DataAccess.Schemas { + public static class AuthorizationTable { + public const string TableName = "Authorize"; + public static readonly DatabaseColumn AuthID = new DatabaseColumn( TableName, "AuthID" ); + public static readonly DatabaseColumn UserName = new DatabaseColumn( TableName, "UserName" ); + public static readonly DatabaseColumn Password = new DatabaseColumn( TableName, "Password" ); + public static readonly DatabaseColumn CustomerID = new DatabaseColumn( TableName, "CustomerID" ); + } +} \ No newline at end of file diff --git a/slips/src/app/Marina/DataAccess/Schemas/BoatTable.cs b/slips/src/app/Marina/DataAccess/Schemas/BoatTable.cs new file mode 100644 index 0000000..3d4fe6b --- /dev/null +++ b/slips/src/app/Marina/DataAccess/Schemas/BoatTable.cs @@ -0,0 +1,11 @@ +namespace Marina.DataAccess.Schemas { + public static class BoatTable { + public const string TableName = "Boat"; + public static readonly DatabaseColumn BoatID = new DatabaseColumn( TableName, "BoatID" ); + public static readonly DatabaseColumn RegistrationNumber = new DatabaseColumn( TableName, "RegistrationNumber" ); + public static readonly DatabaseColumn Manufacturer = new DatabaseColumn( TableName, "Manufacturer" ); + public static readonly DatabaseColumn ModelYear = new DatabaseColumn( TableName, "ModelYear" ); + public static readonly DatabaseColumn Length = new DatabaseColumn( TableName, "Length" ); + public static readonly DatabaseColumn CustomerID = new DatabaseColumn( TableName, "CustomerID" ); + } +} \ No newline at end of file diff --git a/slips/src/app/Marina/DataAccess/Schemas/CustomerTable.cs b/slips/src/app/Marina/DataAccess/Schemas/CustomerTable.cs new file mode 100644 index 0000000..b719a75 --- /dev/null +++ b/slips/src/app/Marina/DataAccess/Schemas/CustomerTable.cs @@ -0,0 +1,10 @@ +namespace Marina.DataAccess.Schemas { + public static class CustomerTable { + public const string TableName = "Customer"; + public static readonly DatabaseColumn CustomerID = new DatabaseColumn( TableName, "CustomerID" ); + public static readonly DatabaseColumn FirstName = new DatabaseColumn( TableName, "FirstName" ); + public static readonly DatabaseColumn LastName = new DatabaseColumn( TableName, "LastName" ); + public static readonly DatabaseColumn Phone = new DatabaseColumn( TableName, "Phone" ); + public static readonly DatabaseColumn City = new DatabaseColumn( TableName, "City" ); + } +} \ No newline at end of file diff --git a/slips/src/app/Marina/DataAccess/Schemas/DockTable.cs b/slips/src/app/Marina/DataAccess/Schemas/DockTable.cs new file mode 100644 index 0000000..1350e82 --- /dev/null +++ b/slips/src/app/Marina/DataAccess/Schemas/DockTable.cs @@ -0,0 +1,10 @@ +namespace Marina.DataAccess.Schemas { + public static class DockTable { + public const string TableName = "Dock"; + public static readonly DatabaseColumn DockID = new DatabaseColumn( TableName, "DockID" ); + public static readonly DatabaseColumn DockName = new DatabaseColumn( TableName, "DockName" ); + public static readonly DatabaseColumn LocationId = new DatabaseColumn( TableName, "LocationId" ); + public static readonly DatabaseColumn WaterService = new DatabaseColumn( TableName, "WaterService" ); + public static readonly DatabaseColumn ElectricalService = new DatabaseColumn( TableName, "ElectricalService" ); + } +} \ No newline at end of file diff --git a/slips/src/app/Marina/DataAccess/Schemas/LeaseTable.cs b/slips/src/app/Marina/DataAccess/Schemas/LeaseTable.cs new file mode 100644 index 0000000..2581372 --- /dev/null +++ b/slips/src/app/Marina/DataAccess/Schemas/LeaseTable.cs @@ -0,0 +1,11 @@ +namespace Marina.DataAccess.Schemas { + public static class LeaseTable { + public const string TableName = "Lease"; + public static readonly DatabaseColumn ID = new DatabaseColumn( TableName, "LeaseID" ); + public static readonly DatabaseColumn StartDate = new DatabaseColumn( TableName, "StartDate" ); + public static readonly DatabaseColumn EndDate = new DatabaseColumn( TableName, "EndDate" ); + public static readonly DatabaseColumn SlipID = new DatabaseColumn( TableName, "SlipID" ); + public static readonly DatabaseColumn CustomerID = new DatabaseColumn( TableName, "CustomerID" ); + public static readonly DatabaseColumn LeaseTypeID = new DatabaseColumn( TableName, "LeaseTypeID" ); + } +} \ No newline at end of file diff --git a/slips/src/app/Marina/DataAccess/Schemas/LeaseType.cs b/slips/src/app/Marina/DataAccess/Schemas/LeaseType.cs new file mode 100644 index 0000000..c36cae9 --- /dev/null +++ b/slips/src/app/Marina/DataAccess/Schemas/LeaseType.cs @@ -0,0 +1,8 @@ +namespace Marina.DataAccess.Schemas { + public static class LeaseType { + public const string TableName = "LeaseType"; + public static readonly DatabaseColumn LeaseTypeID = new DatabaseColumn( TableName, "LeaseTypeID" ); + public static readonly DatabaseColumn LeaseTypeName = new DatabaseColumn( TableName, "LeaseTypeName" ); + public static readonly DatabaseColumn StandardRateAmount = new DatabaseColumn( TableName, "StandardRateAmount" ); + } +} \ No newline at end of file diff --git a/slips/src/app/Marina/DataAccess/Schemas/LocationTable.cs b/slips/src/app/Marina/DataAccess/Schemas/LocationTable.cs new file mode 100644 index 0000000..eadee0b --- /dev/null +++ b/slips/src/app/Marina/DataAccess/Schemas/LocationTable.cs @@ -0,0 +1,7 @@ +namespace Marina.DataAccess.Schemas { + public class LocationTable { + public const string TableName = "Location"; + public static readonly DatabaseColumn ID = new DatabaseColumn( TableName, "LocationId" ); + public static readonly DatabaseColumn Name = new DatabaseColumn( TableName, "LocationName" ); + } +} \ No newline at end of file diff --git a/slips/src/app/Marina/DataAccess/Schemas/SlipTable.cs b/slips/src/app/Marina/DataAccess/Schemas/SlipTable.cs new file mode 100644 index 0000000..fd69733 --- /dev/null +++ b/slips/src/app/Marina/DataAccess/Schemas/SlipTable.cs @@ -0,0 +1,9 @@ +namespace Marina.DataAccess.Schemas { + public static class SlipTable { + public const string TableName = "Slip"; + public static readonly DatabaseColumn ID = new DatabaseColumn( TableName, "SlipID" ); + public static readonly DatabaseColumn Width = new DatabaseColumn( TableName, "SlipWidth" ); + public static readonly DatabaseColumn Length = new DatabaseColumn( TableName, "SlipLength" ); + public static readonly DatabaseColumn DockID = new DatabaseColumn( TableName, "DockID" ); + } +} \ No newline at end of file diff --git a/slips/src/app/Marina/Domain/Boat.cs b/slips/src/app/Marina/Domain/Boat.cs new file mode 100644 index 0000000..3f07174 --- /dev/null +++ b/slips/src/app/Marina/Domain/Boat.cs @@ -0,0 +1,72 @@ +using System; +using Marina.Domain.Interfaces; + +namespace Marina.Domain { + public class Boat : DomainObject, IBoat, IEquatable< Boat > { + public Boat( string registrationNumber, string manufacturer, DateTime yearOfModel, long length ) + : this( -1, registrationNumber, manufacturer, yearOfModel, length ) {} + + public Boat( long id, string registrationNumber, string manufacturer, DateTime yearOfModel, long length ) + : base( id ) { + _registrationNumber = registrationNumber; + _manufacturer = manufacturer; + _yearOfModel = yearOfModel; + _length = length; + } + + public string RegistrationNumber() { + return _registrationNumber; + } + + public string Manufacturer() { + return _manufacturer; + } + + public DateTime YearOfModel() { + return _yearOfModel; + } + + public long LengthInFeet() { + return _length; + } + + public bool Equals( Boat boat ) { + if ( boat == null ) { + return false; + } + if ( !Equals( _registrationNumber, boat._registrationNumber ) ) { + return false; + } + if ( !Equals( _manufacturer, boat._manufacturer ) ) { + return false; + } + if ( !Equals( _yearOfModel, boat._yearOfModel ) ) { + return false; + } + if ( _length != boat._length ) { + return false; + } + return true; + } + + public override bool Equals( object obj ) { + if ( ReferenceEquals( this, obj ) ) { + return true; + } + return Equals( obj as Boat ); + } + + public override int GetHashCode() { + int result = _registrationNumber != null ? _registrationNumber.GetHashCode( ) : 0; + result = 29*result + ( _manufacturer != null ? _manufacturer.GetHashCode( ) : 0 ); + result = 29*result + _yearOfModel.GetHashCode( ); + result = 29*result + ( int )_length; + return result; + } + + private readonly string _registrationNumber; + private readonly string _manufacturer; + private readonly DateTime _yearOfModel; + private readonly long _length; + } +} \ No newline at end of file diff --git a/slips/src/app/Marina/Domain/BrokenRule.cs b/slips/src/app/Marina/Domain/BrokenRule.cs new file mode 100644 index 0000000..1d7d56b --- /dev/null +++ b/slips/src/app/Marina/Domain/BrokenRule.cs @@ -0,0 +1,15 @@ +using Marina.Domain.Interfaces; + +namespace Marina.Domain { + internal class BrokenRule : IBrokenRule { + public BrokenRule( string message ) { + _message = message; + } + + public string Message() { + return _message; + } + + private readonly string _message; + } +} \ No newline at end of file diff --git a/slips/src/app/Marina/Domain/Customer.cs b/slips/src/app/Marina/Domain/Customer.cs new file mode 100644 index 0000000..8b9911c --- /dev/null +++ b/slips/src/app/Marina/Domain/Customer.cs @@ -0,0 +1,76 @@ +using System; +using System.Collections.Generic; +using Marina.Domain.Exceptions; +using Marina.Domain.Interfaces; +using Marina.Infrastructure; + +namespace Marina.Domain { + public class Customer : DomainObject, ICustomer { + public Customer() + : this( -1, new RichList< IBoat >( ), new RichList< ISlipLease >( ), CustomerRegistration.BlankRegistration( ) ) {} + + public Customer( long id, IEnumerable< IBoat > registeredBoats, IEnumerable< ISlipLease > leases, + IRegistration registration ) : base( id ) { + _registeredBoats = ListFactory.From( registeredBoats ); + _leases = ListFactory.From( leases ); + _registration = registration; + } + + public IRegistration Registration() { + return _registration; + } + + public void RegisterAccount( string username, string password, string firstName, string lastName, string phoneNumber, + string city ) { + _registration = new CustomerRegistration( username, password, firstName, lastName, phoneNumber, city ); + } + + public void UpdateRegistrationTo( string username, string password, string firstName, string lastName, + string phoneNumber, + string city ) { + UpdateRegistrationTo( new CustomerRegistration( username, password, firstName, lastName, phoneNumber, city ) ); + } + + public void UpdateRegistrationTo( IRegistration registration ) { + _registration = registration ?? _registration; + } + + public void RegisterBoat( string registrationNumber, string manufacturer, DateTime yearOfModel, long length ) { + RegisterBoat( new Boat( registrationNumber, manufacturer, yearOfModel, length ) ); + } + + public void RegisterBoat( IBoat unregisteredBoat ) { + if ( !IsBoatRegistered( unregisteredBoat ) ) { + _registeredBoats.Add( unregisteredBoat ); + } + } + + public IEnumerable< IBoat > RegisteredBoats() { + return _registeredBoats.All( ); + } + + public void Lease( ISlip slip, ILeaseDuration duration ) { + EnsureSlipIsNotLeased( slip ); + _leases.Add( slip.LeaseTo( this, duration ) ); + } + + public IEnumerable< ISlipLease > Leases() { + return _leases.All( ); + } + + private void EnsureSlipIsNotLeased( ISlip slip ) { + if ( slip.IsLeased( ) ) { + throw new SlipIsAlreadyLeasedException( ); + } + } + + private bool IsBoatRegistered( IBoat boat ) { + return _registeredBoats.Contains( boat ); + } + + private readonly IRichList< IBoat > _registeredBoats; + private readonly IRichList< ISlipLease > _leases; + private IRegistration _registration; + public static readonly ICustomer Unknown = new UnknownCustomer( ); + } +} \ No newline at end of file diff --git a/slips/src/app/Marina/Domain/CustomerRegistration.cs b/slips/src/app/Marina/Domain/CustomerRegistration.cs new file mode 100644 index 0000000..9e7b13b --- /dev/null +++ b/slips/src/app/Marina/Domain/CustomerRegistration.cs @@ -0,0 +1,151 @@ +using System; +using System.Collections.Generic; +using Marina.Domain.Interfaces; + +namespace Marina.Domain { + public class CustomerRegistration : IRegistration, IEquatable< CustomerRegistration > { + private CustomerRegistration() + : this( string.Empty, string.Empty, string.Empty, string.Empty, string.Empty, string.Empty ) {} + + public CustomerRegistration( string userName, string password, string firstName, string lastName, string phoneNumber, + string city ) { + _userName = userName; + _password = password; + _firstName = firstName; + _lastName = lastName; + _phoneNumber = phoneNumber; + _city = city; + } + + public string Username() { + return _userName; + } + + public string Password() { + return _password; + } + + public string FirstName() { + return _firstName; + } + + public string LastName() { + return _lastName; + } + + public string PhoneNumber() { + return _phoneNumber; + } + + public string City() { + return _city; + } + + public bool IsValid() { + foreach ( IBusinessRule businessRule in AllRules( ) ) { + if ( !businessRule.IsBroken( ) ) { + return false; + } + } + return true; + } + + public IEnumerable< IBrokenRule > BrokenRules() { + foreach ( IBusinessRule businessRule in AllRules( ) ) { + if ( !businessRule.IsBroken( ) ) { + yield return businessRule.Description( ); + } + } + } + + private IEnumerable< IBusinessRule > AllRules() { + yield return new PasswordRule( _password ); + yield return new UserNameRule( _userName ); + } + + public bool Equals( CustomerRegistration customerRegistration ) { + if ( customerRegistration == null ) { + return false; + } + if ( !Equals( _userName, customerRegistration._userName ) ) { + return false; + } + if ( !Equals( _password, customerRegistration._password ) ) { + return false; + } + if ( !Equals( _firstName, customerRegistration._firstName ) ) { + return false; + } + if ( !Equals( _lastName, customerRegistration._lastName ) ) { + return false; + } + if ( !Equals( _phoneNumber, customerRegistration._phoneNumber ) ) { + return false; + } + if ( !Equals( _city, customerRegistration._city ) ) { + return false; + } + return true; + } + + public override bool Equals( object obj ) { + if ( ReferenceEquals( this, obj ) ) { + return true; + } + return Equals( obj as CustomerRegistration ); + } + + public override int GetHashCode() { + int result = _userName != null ? _userName.GetHashCode( ) : 0; + result = 29*result + ( _password != null ? _password.GetHashCode( ) : 0 ); + result = 29*result + ( _firstName != null ? _firstName.GetHashCode( ) : 0 ); + result = 29*result + ( _lastName != null ? _lastName.GetHashCode( ) : 0 ); + result = 29*result + ( _phoneNumber != null ? _phoneNumber.GetHashCode( ) : 0 ); + result = 29*result + ( _city != null ? _city.GetHashCode( ) : 0 ); + return result; + } + + private readonly string _userName; + private readonly string _password; + private readonly string _firstName; + private readonly string _lastName; + private readonly string _phoneNumber; + private readonly string _city; + + private class PasswordRule : IBusinessRule { + private readonly string _password; + + public PasswordRule( string password ) { + _password = password; + } + + public bool IsBroken() { + return !string.IsNullOrEmpty( _password ); + } + + public IBrokenRule Description() { + return new BrokenRule( "Password cannot be blank" ); + } + } + + private class UserNameRule : IBusinessRule { + private readonly string _userName; + + public UserNameRule( string userName ) { + _userName = userName; + } + + public bool IsBroken() { + return !string.IsNullOrEmpty( _userName ); + } + + public IBrokenRule Description() { + return new BrokenRule( "Username cannot be blank" ); + } + } + + public static IRegistration BlankRegistration() { + return new CustomerRegistration( ); + } + } +} \ No newline at end of file diff --git a/slips/src/app/Marina/Domain/DateRange.cs b/slips/src/app/Marina/Domain/DateRange.cs new file mode 100644 index 0000000..7460489 --- /dev/null +++ b/slips/src/app/Marina/Domain/DateRange.cs @@ -0,0 +1,22 @@ +using System; +using Marina.Domain.Interfaces; + +namespace Marina.Domain { + internal class DateRange : IDateRange { + public DateRange( DateTime startDate, DateTime endDate ) { + _startDate = startDate; + _endDate = endDate; + } + + public DateTime Start() { + return _startDate; + } + + public DateTime End() { + return _endDate; + } + + private readonly DateTime _startDate; + private readonly DateTime _endDate; + } +} \ No newline at end of file diff --git a/slips/src/app/Marina/Domain/Dock.cs b/slips/src/app/Marina/Domain/Dock.cs new file mode 100644 index 0000000..6900cec --- /dev/null +++ b/slips/src/app/Marina/Domain/Dock.cs @@ -0,0 +1,33 @@ +using Marina.Domain.Interfaces; + +namespace Marina.Domain { + public class Dock : IDock { + private readonly long _id; + private readonly string _name; + private readonly ILocation _location; + private readonly IUtility _utility; + + public Dock( long id, string name, ILocation location, IUtility utility ) { + _id = id; + _name = name; + _location = location; + _utility = utility; + } + + public long ID() { + return _id; + } + + public string Name() { + return _name; + } + + public ILocation Location() { + return _location; + } + + public bool IsUtilityEnabled( IUtility utility ) { + return _utility.IsEnabled( utility ); + } + } +} \ No newline at end of file diff --git a/slips/src/app/Marina/Domain/DomainObject.cs b/slips/src/app/Marina/Domain/DomainObject.cs new file mode 100644 index 0000000..2fefda9 --- /dev/null +++ b/slips/src/app/Marina/Domain/DomainObject.cs @@ -0,0 +1,19 @@ +using Marina.Domain.Interfaces; + +namespace Marina.Domain { + public class DomainObject : IDomainObject { + private long _id; + + public DomainObject( long id ) { + _id = id; + } + + public long ID() { + return _id; + } + + void IDomainObject.ChangeIdTo( long id ) { + _id = id; + } + } +} \ No newline at end of file diff --git a/slips/src/app/Marina/Domain/Exceptions/SlipIsAlreadyLeasedException.cs b/slips/src/app/Marina/Domain/Exceptions/SlipIsAlreadyLeasedException.cs new file mode 100644 index 0000000..be492b7 --- /dev/null +++ b/slips/src/app/Marina/Domain/Exceptions/SlipIsAlreadyLeasedException.cs @@ -0,0 +1,5 @@ +using System; + +namespace Marina.Domain.Exceptions { + public class SlipIsAlreadyLeasedException : Exception {} +} \ No newline at end of file diff --git a/slips/src/app/Marina/Domain/Interfaces/IBoat.cs b/slips/src/app/Marina/Domain/Interfaces/IBoat.cs new file mode 100644 index 0000000..1baf363 --- /dev/null +++ b/slips/src/app/Marina/Domain/Interfaces/IBoat.cs @@ -0,0 +1,13 @@ +using System; + +namespace Marina.Domain.Interfaces { + public interface IBoat : IDomainObject { + string RegistrationNumber(); + + string Manufacturer(); + + DateTime YearOfModel(); + + long LengthInFeet(); + } +} \ No newline at end of file diff --git a/slips/src/app/Marina/Domain/Interfaces/IBrokenRule.cs b/slips/src/app/Marina/Domain/Interfaces/IBrokenRule.cs new file mode 100644 index 0000000..190dc0b --- /dev/null +++ b/slips/src/app/Marina/Domain/Interfaces/IBrokenRule.cs @@ -0,0 +1,5 @@ +namespace Marina.Domain.Interfaces { + public interface IBrokenRule { + string Message(); + } +} \ No newline at end of file diff --git a/slips/src/app/Marina/Domain/Interfaces/IBusinessRule.cs b/slips/src/app/Marina/Domain/Interfaces/IBusinessRule.cs new file mode 100644 index 0000000..c0d3a79 --- /dev/null +++ b/slips/src/app/Marina/Domain/Interfaces/IBusinessRule.cs @@ -0,0 +1,9 @@ +using Marina.Domain.Interfaces; + +namespace Marina.Domain.Interfaces { + internal interface IBusinessRule { + bool IsBroken(); + + IBrokenRule Description(); + } +} \ No newline at end of file diff --git a/slips/src/app/Marina/Domain/Interfaces/ICustomer.cs b/slips/src/app/Marina/Domain/Interfaces/ICustomer.cs new file mode 100644 index 0000000..677194c --- /dev/null +++ b/slips/src/app/Marina/Domain/Interfaces/ICustomer.cs @@ -0,0 +1,27 @@ +using System; +using System.Collections.Generic; + +namespace Marina.Domain.Interfaces { + public interface ICustomer : IDomainObject { + void RegisterBoat( string registrationNumber, string manufacturer, DateTime yearOfModel, long length ); + + void RegisterBoat( IBoat unregisteredBoat ); + + IEnumerable< IBoat > RegisteredBoats(); + + void Lease( ISlip slip, ILeaseDuration duration ); + + IEnumerable< ISlipLease > Leases(); + + IRegistration Registration(); + + void RegisterAccount( string username, string password, string firstName, + string lastName, string phoneNumber, string city ); + + void UpdateRegistrationTo( IRegistration registration ); + + void UpdateRegistrationTo( string username, string password, string firstName, string lastName, + string phoneNumber, + string city ); + } +} \ No newline at end of file diff --git a/slips/src/app/Marina/Domain/Interfaces/IDateRange.cs b/slips/src/app/Marina/Domain/Interfaces/IDateRange.cs new file mode 100644 index 0000000..ec53b90 --- /dev/null +++ b/slips/src/app/Marina/Domain/Interfaces/IDateRange.cs @@ -0,0 +1,9 @@ +using System; + +namespace Marina.Domain.Interfaces { + public interface IDateRange { + DateTime Start(); + + DateTime End(); + } +} \ No newline at end of file diff --git a/slips/src/app/Marina/Domain/Interfaces/IDock.cs b/slips/src/app/Marina/Domain/Interfaces/IDock.cs new file mode 100644 index 0000000..add87fb --- /dev/null +++ b/slips/src/app/Marina/Domain/Interfaces/IDock.cs @@ -0,0 +1,11 @@ +namespace Marina.Domain.Interfaces { + public interface IDock { + long ID(); + + string Name(); + + ILocation Location(); + + bool IsUtilityEnabled( IUtility utility ); + } +} \ No newline at end of file diff --git a/slips/src/app/Marina/Domain/Interfaces/IDomainObject.cs b/slips/src/app/Marina/Domain/Interfaces/IDomainObject.cs new file mode 100644 index 0000000..c8a2c17 --- /dev/null +++ b/slips/src/app/Marina/Domain/Interfaces/IDomainObject.cs @@ -0,0 +1,7 @@ +namespace Marina.Domain.Interfaces { + public interface IDomainObject { + long ID(); + + void ChangeIdTo( long id ); + } +} \ No newline at end of file diff --git a/slips/src/app/Marina/Domain/Interfaces/ILeaseDuration.cs b/slips/src/app/Marina/Domain/Interfaces/ILeaseDuration.cs new file mode 100644 index 0000000..402398d --- /dev/null +++ b/slips/src/app/Marina/Domain/Interfaces/ILeaseDuration.cs @@ -0,0 +1,10 @@ +using System; +using Marina.Infrastructure; + +namespace Marina.Domain.Interfaces { + public interface ILeaseDuration : IDomainObject, ISpecification< IDateRange > { + DateTime CalculateExpiryDateFrom( DateTime startDate ); + + string Name(); + } +} \ No newline at end of file diff --git a/slips/src/app/Marina/Domain/Interfaces/ILeaseType.cs b/slips/src/app/Marina/Domain/Interfaces/ILeaseType.cs new file mode 100644 index 0000000..1fb50b9 --- /dev/null +++ b/slips/src/app/Marina/Domain/Interfaces/ILeaseType.cs @@ -0,0 +1,7 @@ +namespace Marina.Domain.Interfaces { + public interface ILeaseType { + string Name(); + + double Rate(); + } +} \ No newline at end of file diff --git a/slips/src/app/Marina/Domain/Interfaces/ILocation.cs b/slips/src/app/Marina/Domain/Interfaces/ILocation.cs new file mode 100644 index 0000000..2464e8c --- /dev/null +++ b/slips/src/app/Marina/Domain/Interfaces/ILocation.cs @@ -0,0 +1,5 @@ +namespace Marina.Domain.Interfaces { + public interface ILocation { + string Name(); + } +} \ No newline at end of file diff --git a/slips/src/app/Marina/Domain/Interfaces/IRange.cs b/slips/src/app/Marina/Domain/Interfaces/IRange.cs new file mode 100644 index 0000000..e18cc33 --- /dev/null +++ b/slips/src/app/Marina/Domain/Interfaces/IRange.cs @@ -0,0 +1,11 @@ +using System; + +namespace Marina.Domain.Interfaces { + public interface IRange< T > where T : IComparable< T > { + T Start(); + + T End(); + + bool Contains( T value ); + } +} \ No newline at end of file diff --git a/slips/src/app/Marina/Domain/Interfaces/IRegistration.cs b/slips/src/app/Marina/Domain/Interfaces/IRegistration.cs new file mode 100644 index 0000000..de470c6 --- /dev/null +++ b/slips/src/app/Marina/Domain/Interfaces/IRegistration.cs @@ -0,0 +1,22 @@ +using System.Collections.Generic; +using Marina.Domain.Interfaces; + +namespace Marina.Domain.Interfaces { + public interface IRegistration { + string Username(); + + string Password(); + + string FirstName(); + + string LastName(); + + string PhoneNumber(); + + string City(); + + bool IsValid(); + + IEnumerable< IBrokenRule > BrokenRules(); + } +} \ No newline at end of file diff --git a/slips/src/app/Marina/Domain/Interfaces/ISlip.cs b/slips/src/app/Marina/Domain/Interfaces/ISlip.cs new file mode 100644 index 0000000..8ae576c --- /dev/null +++ b/slips/src/app/Marina/Domain/Interfaces/ISlip.cs @@ -0,0 +1,15 @@ +namespace Marina.Domain.Interfaces { + public interface ISlip : IDomainObject { + IDock Dock(); + + ILocation Location(); + + int Width(); + + int Length(); + + ISlipLease LeaseTo( ICustomer customer, ILeaseDuration duration ); + + bool IsLeased(); + } +} \ No newline at end of file diff --git a/slips/src/app/Marina/Domain/Interfaces/ISlipLease.cs b/slips/src/app/Marina/Domain/Interfaces/ISlipLease.cs new file mode 100644 index 0000000..219fb27 --- /dev/null +++ b/slips/src/app/Marina/Domain/Interfaces/ISlipLease.cs @@ -0,0 +1,13 @@ +using System; + +namespace Marina.Domain.Interfaces { + public interface ISlipLease { + ILeaseDuration Duration(); + + DateTime StartDate(); + + DateTime ExpiryDate(); + + ISlip Slip(); + } +} \ No newline at end of file diff --git a/slips/src/app/Marina/Domain/Interfaces/IUtility.cs b/slips/src/app/Marina/Domain/Interfaces/IUtility.cs new file mode 100644 index 0000000..77954d9 --- /dev/null +++ b/slips/src/app/Marina/Domain/Interfaces/IUtility.cs @@ -0,0 +1,5 @@ +namespace Marina.Domain.Interfaces { + public interface IUtility { + bool IsEnabled( IUtility utility ); + } +} \ No newline at end of file diff --git a/slips/src/app/Marina/Domain/LeaseDurations.cs b/slips/src/app/Marina/Domain/LeaseDurations.cs new file mode 100644 index 0000000..e87e567 --- /dev/null +++ b/slips/src/app/Marina/Domain/LeaseDurations.cs @@ -0,0 +1,62 @@ +using System; +using System.Collections.Generic; +using Marina.Domain.Interfaces; + +namespace Marina.Domain { + public class LeaseDurations { + public static readonly ILeaseDuration Daily = new LeaseDuration( "Daily", 1, 1 ); + public static readonly ILeaseDuration Weekly = new LeaseDuration( "Weekly", 2, 7 ); + public static readonly ILeaseDuration Monthly = new LeaseDuration( "Monthly", 3, 30 ); + public static readonly ILeaseDuration Yearly = new LeaseDuration( "Yearly", 4, 365 ); + private static readonly ILeaseDuration NoDuration = new LeaseDuration( "No Duration", -1, 0 ); + private static readonly ILeaseDuration UnknownDuration = new LeaseDuration( "Unknown", -1, 0 ); + + private class LeaseDuration : DomainObject, ILeaseDuration { + private readonly int _days; + private readonly string _name; + + public LeaseDuration( string name, long id, int days ) : base( id ) { + _days = days; + _name = name; + } + + public DateTime CalculateExpiryDateFrom( DateTime startDate ) { + return startDate.AddDays( _days ).Date.AddHours( 11 ); + } + + public string Name() { + return _name; + } + + public bool IsSatisfiedBy( IDateRange range ) { + TimeSpan daysInRange = range.End( ).Subtract( range.Start( ) ); + return _days <= daysInRange.Days; + } + } + + public static ILeaseDuration FindFor( DateTime startDate, DateTime endDate ) { + foreach ( ILeaseDuration duration in AllDurations( ) ) { + if ( duration.IsSatisfiedBy( new DateRange( startDate, endDate ) ) ) { + return duration; + } + } + return NoDuration; + } + + private static IEnumerable< ILeaseDuration > AllDurations() { + yield return Yearly; + yield return Monthly; + yield return Weekly; + yield return Daily; + } + + public static ILeaseDuration FindBy( string duration ) { + foreach ( ILeaseDuration leaseDuration in AllDurations( ) ) { + if ( string.Compare( leaseDuration.Name( ), duration, true ) == 0 ) { + return leaseDuration; + } + } + return UnknownDuration; + } + } +} \ No newline at end of file diff --git a/slips/src/app/Marina/Domain/Location.cs b/slips/src/app/Marina/Domain/Location.cs new file mode 100644 index 0000000..eb68748 --- /dev/null +++ b/slips/src/app/Marina/Domain/Location.cs @@ -0,0 +1,15 @@ +using Marina.Domain.Interfaces; + +namespace Marina.Domain { + public class Location : ILocation { + public Location( string name ) { + _name = name; + } + + public string Name() { + return _name; + } + + private readonly string _name; + } +} \ No newline at end of file diff --git a/slips/src/app/Marina/Domain/Range.cs b/slips/src/app/Marina/Domain/Range.cs new file mode 100644 index 0000000..4b76b25 --- /dev/null +++ b/slips/src/app/Marina/Domain/Range.cs @@ -0,0 +1,32 @@ +using System; +using Marina.Domain.Interfaces; + +namespace Marina.Domain { + public class Range< T > : IRange< T > where T : IComparable< T > { + private readonly T start; + private readonly T end; + + public Range( T start, T end ) { + if ( start.CompareTo( end ) <= 0 ) { + this.start = start; + this.end = end; + } + else { + this.start = end; + this.end = start; + } + } + + public T Start() { + return start; + } + + public T End() { + return end; + } + + public bool Contains( T value ) { + return value.CompareTo( start ) >= 0 && value.CompareTo( end ) <= 0; + } + } +} \ No newline at end of file diff --git a/slips/src/app/Marina/Domain/Repositories/ICustomerRepository.cs b/slips/src/app/Marina/Domain/Repositories/ICustomerRepository.cs new file mode 100644 index 0000000..439bb12 --- /dev/null +++ b/slips/src/app/Marina/Domain/Repositories/ICustomerRepository.cs @@ -0,0 +1,13 @@ +using Marina.Domain.Interfaces; + +namespace Marina.Domain.Repositories { + public interface ICustomerRepository { + ICustomer FindBy( long customerId ); + + ICustomer FindBy( string username ); + + void Save( ICustomer customer ); + + ICustomer NewCustomer(); + } +} \ No newline at end of file diff --git a/slips/src/app/Marina/Domain/Repositories/IDockRepository.cs b/slips/src/app/Marina/Domain/Repositories/IDockRepository.cs new file mode 100644 index 0000000..de9e51f --- /dev/null +++ b/slips/src/app/Marina/Domain/Repositories/IDockRepository.cs @@ -0,0 +1,7 @@ +using Marina.Domain.Interfaces; + +namespace Marina.Domain.Repositories { + public interface IDockRepository { + IDock FindBy( long dockId ); + } +} \ No newline at end of file diff --git a/slips/src/app/Marina/Domain/Repositories/ISlipsRepository.cs b/slips/src/app/Marina/Domain/Repositories/ISlipsRepository.cs new file mode 100644 index 0000000..8a23ca6 --- /dev/null +++ b/slips/src/app/Marina/Domain/Repositories/ISlipsRepository.cs @@ -0,0 +1,12 @@ +using System.Collections.Generic; +using Marina.Domain.Interfaces; + +namespace Marina.Domain.Repositories { + public interface ISlipsRepository { + IEnumerable< ISlip > AllAvailableSlips(); + + IEnumerable< ISlip > AllAvailableSlipsFor( IDock dock ); + + ISlip FindBy( long slipId ); + } +} \ No newline at end of file diff --git a/slips/src/app/Marina/Domain/Slip.cs b/slips/src/app/Marina/Domain/Slip.cs new file mode 100644 index 0000000..6b8a9b7 --- /dev/null +++ b/slips/src/app/Marina/Domain/Slip.cs @@ -0,0 +1,46 @@ +using Marina.Domain.Exceptions; +using Marina.Domain.Interfaces; + +namespace Marina.Domain { + public class Slip : DomainObject, ISlip { + public Slip( long id, IDock dock, int width, int length, bool isLeased ) : base( id ) { + _dock = dock; + _width = width; + _length = length; + _isLeased = isLeased; + } + + public IDock Dock() { + return _dock; + } + + public ILocation Location() { + return _dock.Location( ); + } + + public int Width() { + return _width; + } + + public int Length() { + return _length; + } + + public ISlipLease LeaseTo( ICustomer customer, ILeaseDuration duration ) { + if ( !IsLeased( ) ) { + _isLeased = true; + return new SlipLease( this, duration ); + } + throw new SlipIsAlreadyLeasedException( ); + } + + public bool IsLeased() { + return _isLeased; + } + + private readonly IDock _dock; + private readonly int _width; + private readonly int _length; + private bool _isLeased; + } +} \ No newline at end of file diff --git a/slips/src/app/Marina/Domain/SlipLease.cs b/slips/src/app/Marina/Domain/SlipLease.cs new file mode 100644 index 0000000..297bbf0 --- /dev/null +++ b/slips/src/app/Marina/Domain/SlipLease.cs @@ -0,0 +1,37 @@ +using System; +using Marina.Domain.Interfaces; + +namespace Marina.Domain { + public class SlipLease : ISlipLease { + public SlipLease( ISlip slip, ILeaseDuration duration ) + : this( slip, duration, DateTime.Now.Date, duration.CalculateExpiryDateFrom( DateTime.Now.Date ) ) {} + + public SlipLease( ISlip slip, ILeaseDuration duration, DateTime startDate, DateTime expiryDate ) { + _slip = slip; + _duration = duration; + _startDate = startDate; + _expiryDate = expiryDate; + } + + public ILeaseDuration Duration() { + return _duration; + } + + public DateTime StartDate() { + return _startDate; + } + + public DateTime ExpiryDate() { + return _expiryDate; + } + + public ISlip Slip() { + return _slip; + } + + private readonly ILeaseDuration _duration; + private readonly DateTime _startDate; + private readonly DateTime _expiryDate; + private readonly ISlip _slip; + } +} \ No newline at end of file diff --git a/slips/src/app/Marina/Domain/UnknownCustomer.cs b/slips/src/app/Marina/Domain/UnknownCustomer.cs new file mode 100644 index 0000000..f79f4cc --- /dev/null +++ b/slips/src/app/Marina/Domain/UnknownCustomer.cs @@ -0,0 +1,39 @@ +using System; +using System.Collections.Generic; +using Marina.Domain.Interfaces; + +namespace Marina.Domain { + public class UnknownCustomer : ICustomer { + public void RegisterBoat( string registrationNumber, string manufacturer, DateTime yearOfModel, long length ) {} + + public void RegisterBoat( IBoat unregisteredBoat ) {} + + public IEnumerable< IBoat > RegisteredBoats() { + return new List< IBoat >( ); + } + + public void Lease( ISlip slip, ILeaseDuration duration ) {} + + public IEnumerable< ISlipLease > Leases() { + return new List< ISlipLease >( ); + } + + public IRegistration Registration() { + return CustomerRegistration.BlankRegistration( ); + } + + public void RegisterAccount( string username, string password, string firstName, string lastName, string phoneNumber, + string city ) {} + + public void UpdateRegistrationTo( IRegistration registration ) {} + + public void UpdateRegistrationTo( string username, string password, string firstName, string lastName, + string phoneNumber, string city ) {} + + public long ID() { + return -1; + } + + public void ChangeIdTo( long id ) {} + } +} \ No newline at end of file diff --git a/slips/src/app/Marina/Domain/Utilities.cs b/slips/src/app/Marina/Domain/Utilities.cs new file mode 100644 index 0000000..d318a86 --- /dev/null +++ b/slips/src/app/Marina/Domain/Utilities.cs @@ -0,0 +1,91 @@ +using System; +using System.Collections.Generic; +using System.Text; +using Marina.Domain.Interfaces; + +namespace Marina.Domain { + public class Utilities { + public static readonly IUtility Water = new Utility( "Water" ); + public static readonly IUtility Electrical = new Utility( "Electrical" ); + private static readonly IUtility None = new Utility( "None" ); + + public static IUtility For( params IUtility[] utilities ) { + if ( null != utilities && 0 < utilities.Length ) { + return new UtilityComposite( utilities ); + } + return None; + } + + private class Utility : IUtility, IEquatable< Utility > { + private readonly string _name; + + public Utility( string name ) { + _name = name; + } + + public bool IsEnabled( IUtility utility ) { + return Equals( utility ); + } + + public bool Equals( Utility utility ) { + if ( utility == null ) { + return false; + } + return Equals( _name, utility._name ); + } + + public override bool Equals( object obj ) { + if ( ReferenceEquals( this, obj ) ) { + return true; + } + return Equals( obj as Utility ); + } + + public override int GetHashCode() { + return _name.GetHashCode( ); + } + + public override string ToString() { + return _name; + } + } + + private class UtilityComposite : IUtility { + private readonly IEnumerable< IUtility > _utilities; + + public UtilityComposite( params IUtility[] utilities ) { + _utilities = new List< IUtility >( utilities ); + } + + public bool IsEnabled( IUtility utility ) { + return Equals( utility ); + } + + public override bool Equals( object obj ) { + if ( ReferenceEquals( this, obj ) ) { + return true; + } + foreach ( IUtility utility in _utilities ) { + if ( utility != null ) { + if ( utility.Equals( obj ) ) { + return true; + } + } + } + return false; + } + + public override int GetHashCode() { + return 0; + } + + public override string ToString() { + StringBuilder builder = new StringBuilder( ); + foreach ( IUtility utility in _utilities ) { + builder.Append( utility.ToString( ) ); + } + return builder.ToString( ); + } + } + } +} \ No newline at end of file diff --git a/slips/src/app/Marina/Infrastructure/BlankCommand.cs b/slips/src/app/Marina/Infrastructure/BlankCommand.cs new file mode 100644 index 0000000..8fd0931 --- /dev/null +++ b/slips/src/app/Marina/Infrastructure/BlankCommand.cs @@ -0,0 +1,5 @@ +namespace Marina.Infrastructure { + public class BlankCommand : ICommand { + public void Execute( ) {} + } +} \ No newline at end of file diff --git a/slips/src/app/Marina/Infrastructure/Configuration/ConfigurationItem.cs b/slips/src/app/Marina/Infrastructure/Configuration/ConfigurationItem.cs new file mode 100644 index 0000000..36f512d --- /dev/null +++ b/slips/src/app/Marina/Infrastructure/Configuration/ConfigurationItem.cs @@ -0,0 +1,13 @@ +namespace Marina.Infrastructure.Configuration { + public class ConfigurationItem< T > { + private T item; + + public ConfigurationItem( T item ) { + this.item = item; + } + + public T Value( ) { + return item; + } + } +} \ No newline at end of file diff --git a/slips/src/app/Marina/Infrastructure/Configuration/ConfigurationItems.cs b/slips/src/app/Marina/Infrastructure/Configuration/ConfigurationItems.cs new file mode 100644 index 0000000..9a7973b --- /dev/null +++ b/slips/src/app/Marina/Infrastructure/Configuration/ConfigurationItems.cs @@ -0,0 +1,15 @@ +using System.Configuration; +using System.Xml; + +namespace Marina.Infrastructure.Configuration { + public class ConfigurationItems { + public static readonly ConfigurationItem< XmlElement > Log4NetConfigFile = new ConfigurationItem< XmlElement >( + LoadLog4NetConfig( ) ); + + private static XmlElement LoadLog4NetConfig( ) { + XmlDocument document = new XmlDocument( ); + document.Load( ConfigurationManager.AppSettings[ "LogFileName" ] ); + return document.DocumentElement; + } + } +} \ No newline at end of file diff --git a/slips/src/app/Marina/Infrastructure/Container/Custom/CustomDependencyContainer.cs b/slips/src/app/Marina/Infrastructure/Container/Custom/CustomDependencyContainer.cs new file mode 100644 index 0000000..d37e452 --- /dev/null +++ b/slips/src/app/Marina/Infrastructure/Container/Custom/CustomDependencyContainer.cs @@ -0,0 +1,21 @@ +using System; +using System.Collections.Generic; + +namespace Marina.Infrastructure.Container.Custom { + public class CustomDependencyContainer : IDependencyContainer { + private static IDictionary< Type, object > list; + + public CustomDependencyContainer( ) { + list = new Dictionary< Type, object >( ); + } + + public Interface GetMeAnImplementationOfAn< Interface >( ) { + Type currentType = typeof( Interface ); + return ( Interface )list[ currentType ]; + } + + public void AddImplementationOf< Interface >( Interface objectToRegister ) { + list.Add( typeof( Interface ), objectToRegister ); + } + } +} \ No newline at end of file diff --git a/slips/src/app/Marina/Infrastructure/Container/IDependencyContainer.cs b/slips/src/app/Marina/Infrastructure/Container/IDependencyContainer.cs new file mode 100644 index 0000000..3533e23 --- /dev/null +++ b/slips/src/app/Marina/Infrastructure/Container/IDependencyContainer.cs @@ -0,0 +1,5 @@ +namespace Marina.Infrastructure.Container { + public interface IDependencyContainer { + Interface GetMeAnImplementationOfAn< Interface >( ); + } +} \ No newline at end of file diff --git a/slips/src/app/Marina/Infrastructure/Container/InterfaceResolutionException.cs b/slips/src/app/Marina/Infrastructure/Container/InterfaceResolutionException.cs new file mode 100644 index 0000000..d42b550 --- /dev/null +++ b/slips/src/app/Marina/Infrastructure/Container/InterfaceResolutionException.cs @@ -0,0 +1,11 @@ +using System; + +namespace Marina.Infrastructure.Container { + public class InterfaceResolutionException : Exception { + public const string ExceptionMessageFormat = "Failed to resolve an implementation of an {0}"; + + public InterfaceResolutionException( Exception innerException, Type interfaceThatCouldNotBeResolvedForSomeReason ) + : base( + string.Format( ExceptionMessageFormat, interfaceThatCouldNotBeResolvedForSomeReason.FullName ), innerException ) {} + } +} \ No newline at end of file diff --git a/slips/src/app/Marina/Infrastructure/Container/Resolve.cs b/slips/src/app/Marina/Infrastructure/Container/Resolve.cs new file mode 100644 index 0000000..53e602b --- /dev/null +++ b/slips/src/app/Marina/Infrastructure/Container/Resolve.cs @@ -0,0 +1,21 @@ +using System; + +namespace Marina.Infrastructure.Container { + public class Resolve { + private static IDependencyContainer container; + + public static void InitializeWith( IDependencyContainer newContainer + ) { + container = newContainer; + } + + public static Interface DependencyFor< Interface >() { + try { + return container.GetMeAnImplementationOfAn< Interface >( ); + } + catch ( Exception e ) { + throw new InterfaceResolutionException( e, typeof( Interface ) ); + } + } + } +} \ No newline at end of file diff --git a/slips/src/app/Marina/Infrastructure/Container/Windsor/WindsorDependencyContainer.cs b/slips/src/app/Marina/Infrastructure/Container/Windsor/WindsorDependencyContainer.cs new file mode 100644 index 0000000..c35c6ce --- /dev/null +++ b/slips/src/app/Marina/Infrastructure/Container/Windsor/WindsorDependencyContainer.cs @@ -0,0 +1,16 @@ +using Castle.Windsor; +using Castle.Windsor.Configuration.Interpreters; + +namespace Marina.Infrastructure.Container.Windsor { + public class WindsorDependencyContainer : IDependencyContainer { + private readonly IWindsorContainer _container; + + public WindsorDependencyContainer() { + _container = new WindsorContainer( new XmlInterpreter( @"windsor.config.xml" ) ); + } + + public Interface GetMeAnImplementationOfAn< Interface >() { + return _container.Resolve< Interface >( ); + } + } +} \ No newline at end of file diff --git a/slips/src/app/Marina/Infrastructure/EnumerableMapper.cs b/slips/src/app/Marina/Infrastructure/EnumerableMapper.cs new file mode 100644 index 0000000..0ba9bca --- /dev/null +++ b/slips/src/app/Marina/Infrastructure/EnumerableMapper.cs @@ -0,0 +1,17 @@ +using System.Collections.Generic; + +namespace Marina.Infrastructure { + internal class EnumerableMapper< TIn, TOut > : IMapper< IEnumerable< TIn >, IEnumerable< TOut > > { + public EnumerableMapper( IMapper< TIn, TOut > mapper ) { + _mapper = mapper; + } + + public IEnumerable< TOut > MapFrom( IEnumerable< TIn > input ) { + foreach ( TIn item in input ) { + yield return _mapper.MapFrom( item ); + } + } + + private readonly IMapper< TIn, TOut > _mapper; + } +} \ No newline at end of file diff --git a/slips/src/app/Marina/Infrastructure/ICommand.cs b/slips/src/app/Marina/Infrastructure/ICommand.cs new file mode 100644 index 0000000..cd98ab5 --- /dev/null +++ b/slips/src/app/Marina/Infrastructure/ICommand.cs @@ -0,0 +1,5 @@ +namespace Marina.Infrastructure { + public interface ICommand { + void Execute( ); + } +} \ No newline at end of file diff --git a/slips/src/app/Marina/Infrastructure/IFactory.cs b/slips/src/app/Marina/Infrastructure/IFactory.cs new file mode 100644 index 0000000..0c835e0 --- /dev/null +++ b/slips/src/app/Marina/Infrastructure/IFactory.cs @@ -0,0 +1,5 @@ +namespace Marina.Infrastructure { + public interface IFactory< T > { + T Create( ); + } +} \ No newline at end of file diff --git a/slips/src/app/Marina/Infrastructure/IMapper.cs b/slips/src/app/Marina/Infrastructure/IMapper.cs new file mode 100644 index 0000000..784bc41 --- /dev/null +++ b/slips/src/app/Marina/Infrastructure/IMapper.cs @@ -0,0 +1,5 @@ +namespace Marina.Infrastructure { + public interface IMapper< TIn, TOut > { + TOut MapFrom( TIn input ); + } +} \ No newline at end of file diff --git a/slips/src/app/Marina/Infrastructure/IRichEnumerable.cs b/slips/src/app/Marina/Infrastructure/IRichEnumerable.cs new file mode 100644 index 0000000..622bdf2 --- /dev/null +++ b/slips/src/app/Marina/Infrastructure/IRichEnumerable.cs @@ -0,0 +1,7 @@ +using System.Collections.Generic; + +namespace Marina.Infrastructure { + public interface IRichEnumerable< T > : IEnumerable< T > { + IEnumerable< T > Where( ISpecification< T > criteriaToSatisfy ); + } +} \ No newline at end of file diff --git a/slips/src/app/Marina/Infrastructure/IRichList.cs b/slips/src/app/Marina/Infrastructure/IRichList.cs new file mode 100644 index 0000000..3bac655 --- /dev/null +++ b/slips/src/app/Marina/Infrastructure/IRichList.cs @@ -0,0 +1,91 @@ +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; + +namespace Marina.Infrastructure { + public interface IRichList< T > : IList< T > { + void AddRange( IEnumerable< T > collection ); + + ReadOnlyCollection< T > AsReadOnly(); + + int BinarySearch( int index, int count, T item, IComparer< T > comparer ); + + int BinarySearch( T item ); + + int BinarySearch( T item, IComparer< T > comparer ); + + IRichList< TOutput > ConvertAll< TOutput >( Converter< T, TOutput > converter ); + + void CopyTo( T[] array ); + + void CopyTo( int index, T[] array, int arrayIndex, int count ); + + bool Exists( Predicate< T > match ); + + T Find( Predicate< T > match ); + + IRichList< T > FindAll( Predicate< T > match ); + + int FindIndex( Predicate< T > match ); + + int FindIndex( int startIndex, Predicate< T > match ); + + int FindIndex( int startIndex, int count, Predicate< T > match ); + + T FindLast( Predicate< T > match ); + + int FindLastIndex( Predicate< T > match ); + + int FindLastIndex( int startIndex, Predicate< T > match ); + + int FindLastIndex( int startIndex, int count, Predicate< T > match ); + + void ForEach( Action< T > action ); + + IRichList< T > GetRange( int index, int count ); + + int IndexOf( T item, int index ); + + int IndexOf( T item, int index, int count ); + + void InsertRange( int index, IEnumerable< T > collection ); + + int LastIndexOf( T item ); + + int LastIndexOf( T item, int index ); + + int LastIndexOf( T item, int index, int count ); + + int RemoveAll( Predicate< T > match ); + + void RemoveRange( int index, int count ); + + void Reverse(); + + void Reverse( int index, int count ); + + void Sort(); + + void Sort( IComparer< T > comparer ); + + void Sort( int index, int count, IComparer< T > comparer ); + + void Sort( Comparison< T > comparison ); + + T[] ToArray(); + + void TrimExcess(); + + bool TrueForAll( Predicate< T > match ); + + int Capacity { get; set; } + + void VisitAllItemWith( IVisitor< T > visitor ); + + Result GetResultOfVisitingAllItemsWith< Result >( IValueReturningVisitor< Result, T > visitor ); + + IEnumerable< Output > MapAllUsing< Output >( IMapper< T, Output > mapper ); + + IEnumerable< T > All(); + } +} \ No newline at end of file diff --git a/slips/src/app/Marina/Infrastructure/ISpecification.cs b/slips/src/app/Marina/Infrastructure/ISpecification.cs new file mode 100644 index 0000000..852c66f --- /dev/null +++ b/slips/src/app/Marina/Infrastructure/ISpecification.cs @@ -0,0 +1,5 @@ +namespace Marina.Infrastructure { + public interface ISpecification< T > { + bool IsSatisfiedBy( T item ); + } +} \ No newline at end of file diff --git a/slips/src/app/Marina/Infrastructure/ISpecificationBuilder.cs b/slips/src/app/Marina/Infrastructure/ISpecificationBuilder.cs new file mode 100644 index 0000000..14089db --- /dev/null +++ b/slips/src/app/Marina/Infrastructure/ISpecificationBuilder.cs @@ -0,0 +1,5 @@ +namespace Marina.Infrastructure { + public interface ISpecificationBuilder< T > : ISpecification< T > { + ISpecificationBuilder< T > And( ISpecification< T > specification ); + } +} \ No newline at end of file diff --git a/slips/src/app/Marina/Infrastructure/ITransformer.cs b/slips/src/app/Marina/Infrastructure/ITransformer.cs new file mode 100644 index 0000000..4cbb54c --- /dev/null +++ b/slips/src/app/Marina/Infrastructure/ITransformer.cs @@ -0,0 +1,5 @@ +namespace Marina.Infrastructure { + public interface ITransformer { + Item To< Item >( ); + } +} \ No newline at end of file diff --git a/slips/src/app/Marina/Infrastructure/IValueReturningVisitor.cs b/slips/src/app/Marina/Infrastructure/IValueReturningVisitor.cs new file mode 100644 index 0000000..160b039 --- /dev/null +++ b/slips/src/app/Marina/Infrastructure/IValueReturningVisitor.cs @@ -0,0 +1,5 @@ +namespace Marina.Infrastructure { + public interface IValueReturningVisitor< ValueToReturn, T > : IVisitor< T > { + ValueToReturn GetResult( ); + } +} \ No newline at end of file diff --git a/slips/src/app/Marina/Infrastructure/IVisitor.cs b/slips/src/app/Marina/Infrastructure/IVisitor.cs new file mode 100644 index 0000000..6c6e513 --- /dev/null +++ b/slips/src/app/Marina/Infrastructure/IVisitor.cs @@ -0,0 +1,5 @@ +namespace Marina.Infrastructure { + public interface IVisitor< T > { + void Visit( T item ); + } +} \ No newline at end of file diff --git a/slips/src/app/Marina/Infrastructure/ListFactory.cs b/slips/src/app/Marina/Infrastructure/ListFactory.cs new file mode 100644 index 0000000..0e19bcb --- /dev/null +++ b/slips/src/app/Marina/Infrastructure/ListFactory.cs @@ -0,0 +1,20 @@ +using System.Collections.Generic; + +namespace Marina.Infrastructure { + public class ListFactory { + public static IRichList< T > From< T >( IEnumerable< T > items ) { + if ( items == null ) { + return new RichList< T >( ); + } + return new RichList< T >( items ); + } + + public static IEnumerable< T > For< T >( params T[] items ) { + IRichList< T > list = new RichList< T >( ); + foreach ( T item in items ) { + list.Add( item ); + } + return list; + } + } +} \ No newline at end of file diff --git a/slips/src/app/Marina/Infrastructure/Logging/Interfaces/ILog.cs b/slips/src/app/Marina/Infrastructure/Logging/Interfaces/ILog.cs new file mode 100644 index 0000000..37d91d8 --- /dev/null +++ b/slips/src/app/Marina/Infrastructure/Logging/Interfaces/ILog.cs @@ -0,0 +1,7 @@ +namespace Marina.Infrastructure.Logging.Interfaces { + public interface ILog { + void Informational( string message ); + void Informational( string messageFormat, params object[] args ); + void CriticalError( string messageFormat, params object[] args ); + } +} \ No newline at end of file diff --git a/slips/src/app/Marina/Infrastructure/Logging/Interfaces/ILogFactory.cs b/slips/src/app/Marina/Infrastructure/Logging/Interfaces/ILogFactory.cs new file mode 100644 index 0000000..0c71caf --- /dev/null +++ b/slips/src/app/Marina/Infrastructure/Logging/Interfaces/ILogFactory.cs @@ -0,0 +1,7 @@ +using System; + +namespace Marina.Infrastructure.Logging.Interfaces { + public interface ILogFactory { + ILog CreateFor( Type type ); + } +} \ No newline at end of file diff --git a/slips/src/app/Marina/Infrastructure/Logging/Interfaces/Log.cs b/slips/src/app/Marina/Infrastructure/Logging/Interfaces/Log.cs new file mode 100644 index 0000000..c8dae76 --- /dev/null +++ b/slips/src/app/Marina/Infrastructure/Logging/Interfaces/Log.cs @@ -0,0 +1,14 @@ +using System; +using Marina.Infrastructure.Container; + +namespace Marina.Infrastructure.Logging.Interfaces { + public class Log { + public static ILog For( object itemThatRequiresLoggingServices ) { + return For( itemThatRequiresLoggingServices.GetType( ) ); + } + + public static ILog For( Type type ) { + return Resolve.DependencyFor< ILogFactory >( ).CreateFor( type ); + } + } +} \ No newline at end of file diff --git a/slips/src/app/Marina/Infrastructure/Logging/Log4Net/ILog4NetInitializationCommand.cs b/slips/src/app/Marina/Infrastructure/Logging/Log4Net/ILog4NetInitializationCommand.cs new file mode 100644 index 0000000..a688728 --- /dev/null +++ b/slips/src/app/Marina/Infrastructure/Logging/Log4Net/ILog4NetInitializationCommand.cs @@ -0,0 +1,8 @@ +using System.Xml; +using log4net.Config; + +namespace Marina.Infrastructure.Logging.Log4Net { + public interface ILog4NetInitializationCommand { + void Execute( ); + } +} \ No newline at end of file diff --git a/slips/src/app/Marina/Infrastructure/Logging/Log4Net/Log4NetInitializationCommand.cs b/slips/src/app/Marina/Infrastructure/Logging/Log4Net/Log4NetInitializationCommand.cs new file mode 100644 index 0000000..888a088 --- /dev/null +++ b/slips/src/app/Marina/Infrastructure/Logging/Log4Net/Log4NetInitializationCommand.cs @@ -0,0 +1,19 @@ +using System.Xml; +using log4net.Config; +using Marina.Infrastructure.Configuration; + +namespace Marina.Infrastructure.Logging.Log4Net { + public class Log4NetInitializationCommand : ILog4NetInitializationCommand { + private readonly XmlElement configuration; + + public Log4NetInitializationCommand( ) : this( ConfigurationItems.Log4NetConfigFile.Value( ) ) {} + + public Log4NetInitializationCommand( XmlElement configuration ) { + this.configuration = configuration; + } + + public void Execute( ) { + XmlConfigurator.Configure( configuration ); + } + } +} \ No newline at end of file diff --git a/slips/src/app/Marina/Infrastructure/Logging/Log4Net/Log4NetLog.cs b/slips/src/app/Marina/Infrastructure/Logging/Log4Net/Log4NetLog.cs new file mode 100644 index 0000000..a225f55 --- /dev/null +++ b/slips/src/app/Marina/Infrastructure/Logging/Log4Net/Log4NetLog.cs @@ -0,0 +1,23 @@ +using Marina.Infrastructure.Logging.Interfaces; + +namespace Marina.Infrastructure.Logging.Log4Net { + public class Log4NetLog : ILog { + private log4net.ILog logToAdapt; + + public Log4NetLog( log4net.ILog logToAdapt ) { + this.logToAdapt = logToAdapt; + } + + public void Informational( string message ) { + logToAdapt.Info( message ); + } + + public void Informational( string messageFormat, params object[] args ) { + logToAdapt.InfoFormat( messageFormat, args ); + } + + public void CriticalError( string messageFormat, params object[] args ) { + logToAdapt.ErrorFormat( messageFormat, args ); + } + } +} \ No newline at end of file diff --git a/slips/src/app/Marina/Infrastructure/Logging/Log4Net/Log4NetLogFactory.cs b/slips/src/app/Marina/Infrastructure/Logging/Log4Net/Log4NetLogFactory.cs new file mode 100644 index 0000000..996557f --- /dev/null +++ b/slips/src/app/Marina/Infrastructure/Logging/Log4Net/Log4NetLogFactory.cs @@ -0,0 +1,30 @@ +using System; +using log4net; +using Marina.Infrastructure.Logging.Interfaces; +using ILog=Marina.Infrastructure.Logging.Interfaces.ILog; + +namespace Marina.Infrastructure.Logging.Log4Net { + public class Log4NetLogFactory : ILogFactory { + private ILog4NetInitializationCommand initializationCommand; + private bool initialized; + + public Log4NetLogFactory( ) : this( new Log4NetInitializationCommand( ) ) {} + + public Log4NetLogFactory( ILog4NetInitializationCommand initializationCommand ) { + this.initializationCommand = initializationCommand; + } + + public ILog CreateFor( Type typeThatRequiresLoggingServices ) { + WireUpConfiguration( ); + return new Log4NetLog( LogManager.GetLogger( typeThatRequiresLoggingServices ) ); + } + + private void WireUpConfiguration( ) { + if ( initialized ) { + return; + } + initialized = true; + initializationCommand.Execute( ); + } + } +} \ No newline at end of file diff --git a/slips/src/app/Marina/Infrastructure/Logging/TextWriterLogging/TextWriterLog.cs b/slips/src/app/Marina/Infrastructure/Logging/TextWriterLogging/TextWriterLog.cs new file mode 100644 index 0000000..858d0f7 --- /dev/null +++ b/slips/src/app/Marina/Infrastructure/Logging/TextWriterLogging/TextWriterLog.cs @@ -0,0 +1,24 @@ +using System.IO; +using Marina.Infrastructure.Logging.Interfaces; + +namespace Marina.Infrastructure.Logging.TextWriterLogging { + public class TextWriterLog : ILog { + private readonly TextWriter _writer; + + public TextWriterLog( TextWriter writer ) { + _writer = writer; + } + + public void Informational( string message ) { + _writer.WriteLine( message ); + } + + public void Informational( string messageFormat, params object[] args ) { + _writer.WriteLine( messageFormat, args ); + } + + public void CriticalError( string messageFormat, params object[] args ) { + Informational( messageFormat, args ); + } + } +} \ No newline at end of file diff --git a/slips/src/app/Marina/Infrastructure/Logging/TextWriterLogging/TextWriterLogFactory.cs b/slips/src/app/Marina/Infrastructure/Logging/TextWriterLogging/TextWriterLogFactory.cs new file mode 100644 index 0000000..7a2b344 --- /dev/null +++ b/slips/src/app/Marina/Infrastructure/Logging/TextWriterLogging/TextWriterLogFactory.cs @@ -0,0 +1,10 @@ +using System; +using Marina.Infrastructure.Logging.Interfaces; + +namespace Marina.Infrastructure.Logging.TextWriterLogging { + public class TextWriterLogFactory : ILogFactory { + public ILog CreateFor( Type type ) { + return new TextWriterLog( Console.Out ); + } + } +} \ No newline at end of file diff --git a/slips/src/app/Marina/Infrastructure/RichEnumerable.cs b/slips/src/app/Marina/Infrastructure/RichEnumerable.cs new file mode 100644 index 0000000..aa5f49d --- /dev/null +++ b/slips/src/app/Marina/Infrastructure/RichEnumerable.cs @@ -0,0 +1,28 @@ +using System.Collections; +using System.Collections.Generic; + +namespace Marina.Infrastructure { + public class RichEnumerable< T > : IRichEnumerable< T > { + private readonly IEnumerable< T > itemsToEnumerate; + + public RichEnumerable( IEnumerable< T > itemsToEnumerate ) { + this.itemsToEnumerate = itemsToEnumerate; + } + + public IEnumerable< T > Where( ISpecification< T > criteriaToSatisfy ) { + foreach ( T item in itemsToEnumerate ) { + if ( criteriaToSatisfy.IsSatisfiedBy( item ) ) { + yield return item; + } + } + } + + IEnumerator< T > IEnumerable< T >.GetEnumerator() { + return itemsToEnumerate.GetEnumerator( ); + } + + public IEnumerator GetEnumerator() { + return ( ( IEnumerable< T > )this ).GetEnumerator( ); + } + } +} \ No newline at end of file diff --git a/slips/src/app/Marina/Infrastructure/RichList.cs b/slips/src/app/Marina/Infrastructure/RichList.cs new file mode 100644 index 0000000..ec6bfa0 --- /dev/null +++ b/slips/src/app/Marina/Infrastructure/RichList.cs @@ -0,0 +1,45 @@ +using System; +using System.Collections.Generic; + +namespace Marina.Infrastructure { + public class RichList< T > : List< T >, IRichList< T > { + public RichList( IEnumerable< T > collection ) + : base( collection ) {} + + public RichList( int capacity ) + : base( capacity ) {} + + public RichList() {} + + public IEnumerable< Output > MapAllUsing< Output >( IMapper< T, Output > mapper ) { + return ConvertAll< Output >( mapper.MapFrom ); + } + + public IEnumerable< T > All() { + foreach ( T t in this ) { + yield return t; + } + } + + public new IRichList< TOutput > ConvertAll< TOutput >( Converter< T, TOutput > converter ) { + return new RichList< TOutput >( base.ConvertAll( converter ) ); + } + + public new IRichList< T > FindAll( Predicate< T > match ) { + return new RichList< T >( base.FindAll( match ) ); + } + + public new IRichList< T > GetRange( int index, int count ) { + return new RichList< T >( base.GetRange( index, count ) ); + } + + public void VisitAllItemWith( IVisitor< T > visitor ) { + ForEach( visitor.Visit ); + } + + public Result GetResultOfVisitingAllItemsWith< Result >( IValueReturningVisitor< Result, T > visitor ) { + VisitAllItemWith( visitor ); + return visitor.GetResult( ); + } + } +} \ No newline at end of file diff --git a/slips/src/app/Marina/Infrastructure/SpecificationBuilder.cs b/slips/src/app/Marina/Infrastructure/SpecificationBuilder.cs new file mode 100644 index 0000000..1651733 --- /dev/null +++ b/slips/src/app/Marina/Infrastructure/SpecificationBuilder.cs @@ -0,0 +1,44 @@ +namespace Marina.Infrastructure { + public class SpecificationBuilder< T > : ISpecificationBuilder< T > { + public SpecificationBuilder() : this( new BlankSpecification( ) ) {} + + public SpecificationBuilder( ISpecification< T > criteria ) { + _criteria = criteria; + } + + public bool IsSatisfiedBy( T item ) { + return _criteria.IsSatisfiedBy( item ); + } + + public ISpecificationBuilder< T > And( ISpecification< T > specification ) { + _criteria = new AndSpecification< T >( _criteria, specification ); + return this; + } + + public ISpecification< T > Build() { + return _criteria; + } + + public class BlankSpecification : ISpecification< T > { + public bool IsSatisfiedBy( T item ) { + return true; + } + } + + private ISpecification< T > _criteria; + + private class AndSpecification< K > : ISpecification< K > { + public AndSpecification( ISpecification< K > leftCriteria, ISpecification< K > rightCriteria ) { + this.leftCriteria = leftCriteria; + this.rightCriteria = rightCriteria; + } + + public bool IsSatisfiedBy( K item ) { + return leftCriteria.IsSatisfiedBy( item ) && rightCriteria.IsSatisfiedBy( item ); + } + + private readonly ISpecification< K > leftCriteria; + private readonly ISpecification< K > rightCriteria; + } + } +} \ No newline at end of file diff --git a/slips/src/app/Marina/Infrastructure/Transform.cs b/slips/src/app/Marina/Infrastructure/Transform.cs new file mode 100644 index 0000000..a47a9bc --- /dev/null +++ b/slips/src/app/Marina/Infrastructure/Transform.cs @@ -0,0 +1,7 @@ +namespace Marina.Infrastructure { + public class Transform { + public static ITransformer From( object item ) { + return new Transformer( item ); + } + } +} \ No newline at end of file diff --git a/slips/src/app/Marina/Infrastructure/Transformer.cs b/slips/src/app/Marina/Infrastructure/Transformer.cs new file mode 100644 index 0000000..bdd59c8 --- /dev/null +++ b/slips/src/app/Marina/Infrastructure/Transformer.cs @@ -0,0 +1,22 @@ +using System; + +namespace Marina.Infrastructure { + public class Transformer : ITransformer { + private object item; + + public Transformer( object item ) { + this.item = item; + } + + public Result To< Result >( ) { + EnsureItemIsNotNull( ); + return ( Result )item; + } + + private void EnsureItemIsNotNull( ) { + if ( item == null ) { + throw new NullReferenceException( ); + } + } + } +} \ No newline at end of file diff --git a/slips/src/app/Marina/Marina.csproj b/slips/src/app/Marina/Marina.csproj new file mode 100644 index 0000000..9fc4466 --- /dev/null +++ b/slips/src/app/Marina/Marina.csproj @@ -0,0 +1,322 @@ + + + + Debug + AnyCPU + 9.0.21022 + 2.0 + {F9AF658A-2A26-49DE-A964-7A846A8DCC2A} + Library + Properties + Marina + Marina + v3.5 + 512 + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + False + ..\..\..\build\lib\castle\bin\Castle.Core.dll + + + False + ..\..\..\build\lib\castle\bin\Castle.DynamicProxy.dll + + + False + ..\..\..\build\lib\castle\bin\Castle.MicroKernel.dll + + + False + ..\..\..\build\lib\castle\bin\Castle.Windsor.dll + + + False + ..\..\..\build\lib\log4net\bin\log4net.dll + + + + + 3.5 + + + + + + + + 3.5 + + + 3.5 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/slips/src/app/Marina/Presentation/DTO/BoatRegistrationDTO.cs b/slips/src/app/Marina/Presentation/DTO/BoatRegistrationDTO.cs new file mode 100644 index 0000000..f34a70f --- /dev/null +++ b/slips/src/app/Marina/Presentation/DTO/BoatRegistrationDTO.cs @@ -0,0 +1,41 @@ +using System; + +namespace Marina.Presentation.DTO { + [Serializable] + public class BoatRegistrationDTO { + private readonly string registrationNumber; + private readonly string manufacturer; + private readonly string modelYear; + private readonly string length; + private readonly long customerId; + + public BoatRegistrationDTO( string registrationNumber, string manufacturer, string modelYear, string length, + long customerId ) { + this.registrationNumber = registrationNumber; + this.manufacturer = manufacturer; + this.modelYear = modelYear; + this.length = length; + this.customerId = customerId; + } + + public string RegistrationNumber { + get { return registrationNumber; } + } + + public string Manufacturer { + get { return manufacturer; } + } + + public string ModelYear { + get { return modelYear; } + } + + public string Length { + get { return length; } + } + + public long CustomerId { + get { return customerId; } + } + } +} \ No newline at end of file diff --git a/slips/src/app/Marina/Presentation/DTO/CustomerRegistrationDisplayDTO.cs b/slips/src/app/Marina/Presentation/DTO/CustomerRegistrationDisplayDTO.cs new file mode 100644 index 0000000..3c517bf --- /dev/null +++ b/slips/src/app/Marina/Presentation/DTO/CustomerRegistrationDisplayDTO.cs @@ -0,0 +1,91 @@ +using System; + +namespace Marina.Presentation.DTO { + [Serializable] + public class CustomerRegistrationDisplayDTO : IEquatable< CustomerRegistrationDisplayDTO > { + private CustomerRegistrationDisplayDTO() {} + + public CustomerRegistrationDisplayDTO( string id, string userName, string firstName, string lastName, string phone, + string city ) { + _userName = userName; + _id = id; + _firstName = firstName; + _lastName = lastName; + _phone = phone; + _city = city; + } + + public string Id { + get { return _id; } + } + + public string UserName { + get { return _userName; } + } + + public string FirstName { + get { return _firstName; } + } + + public string LastName { + get { return _lastName; } + } + + public string Phone { + get { return _phone; } + } + + public string City { + get { return _city; } + } + + public bool Equals( CustomerRegistrationDisplayDTO customerRegistrationDisplayDTO ) { + if ( customerRegistrationDisplayDTO == null ) { + return false; + } + if ( !Equals( _userName, customerRegistrationDisplayDTO._userName ) ) { + return false; + } + if ( !Equals( _firstName, customerRegistrationDisplayDTO._firstName ) ) { + return false; + } + if ( !Equals( _lastName, customerRegistrationDisplayDTO._lastName ) ) { + return false; + } + if ( !Equals( _phone, customerRegistrationDisplayDTO._phone ) ) { + return false; + } + if ( !Equals( _city, customerRegistrationDisplayDTO._city ) ) { + return false; + } + if ( !Equals( _id, customerRegistrationDisplayDTO._id ) ) { + return false; + } + return true; + } + + public override bool Equals( object obj ) { + if ( ReferenceEquals( this, obj ) ) { + return true; + } + return Equals( obj as CustomerRegistrationDisplayDTO ); + } + + public override int GetHashCode() { + int result = _userName != null ? _userName.GetHashCode( ) : 0; + result = 29*result + ( _firstName != null ? _firstName.GetHashCode( ) : 0 ); + result = 29*result + ( _lastName != null ? _lastName.GetHashCode( ) : 0 ); + result = 29*result + ( _phone != null ? _phone.GetHashCode( ) : 0 ); + result = 29*result + ( _city != null ? _city.GetHashCode( ) : 0 ); + result = 29*result + ( _id != null ? _id.GetHashCode( ) : 0 ); + return result; + } + + private string _userName; + private string _firstName; + private string _lastName; + private string _phone; + private string _city; + private string _id; + } +} \ No newline at end of file diff --git a/slips/src/app/Marina/Presentation/DTO/DisplayLeaseDTO.cs b/slips/src/app/Marina/Presentation/DTO/DisplayLeaseDTO.cs new file mode 100644 index 0000000..a8c94cc --- /dev/null +++ b/slips/src/app/Marina/Presentation/DTO/DisplayLeaseDTO.cs @@ -0,0 +1,28 @@ +using System; + +namespace Marina.Presentation.DTO { + [Serializable] + public class DisplayLeaseDTO { + public DisplayLeaseDTO( string slipID, string startDate, string expiryDate ) { + _slipID = slipID; + _startDate = startDate; + _expiryDate = expiryDate; + } + + public string SlipID { + get { return _slipID; } + } + + public string StartDate { + get { return _startDate; } + } + + public string ExpiryDate { + get { return _expiryDate; } + } + + private string _slipID; + private string _startDate; + private string _expiryDate; + } +} \ No newline at end of file diff --git a/slips/src/app/Marina/Presentation/DTO/DisplayResponseLineDTO.cs b/slips/src/app/Marina/Presentation/DTO/DisplayResponseLineDTO.cs new file mode 100644 index 0000000..b245db6 --- /dev/null +++ b/slips/src/app/Marina/Presentation/DTO/DisplayResponseLineDTO.cs @@ -0,0 +1,36 @@ +using System; + +namespace Marina.Presentation.DTO { + [Serializable] + public class DisplayResponseLineDTO : IEquatable< DisplayResponseLineDTO > { + private readonly string _message; + + private DisplayResponseLineDTO() {} + + public DisplayResponseLineDTO( string message ) { + _message = message; + } + + public string Message { + get { return _message; } + } + + public bool Equals( DisplayResponseLineDTO displayResponseLineDTO ) { + if ( displayResponseLineDTO == null ) { + return false; + } + return Equals( _message, displayResponseLineDTO._message ); + } + + public override bool Equals( object obj ) { + if ( ReferenceEquals( this, obj ) ) { + return true; + } + return Equals( obj as DisplayResponseLineDTO ); + } + + public override int GetHashCode() { + return _message != null ? _message.GetHashCode( ) : 0; + } + } +} \ No newline at end of file diff --git a/slips/src/app/Marina/Presentation/DTO/DisplayResponseLines.cs b/slips/src/app/Marina/Presentation/DTO/DisplayResponseLines.cs new file mode 100644 index 0000000..4f8c74c --- /dev/null +++ b/slips/src/app/Marina/Presentation/DTO/DisplayResponseLines.cs @@ -0,0 +1,24 @@ +using System; +using System.Collections; +using System.Collections.Generic; + +namespace Marina.Presentation.DTO { + [Serializable] + public class DisplayResponseLines : IEnumerable< DisplayResponseLineDTO > { + private readonly string[] _lineItems; + + public DisplayResponseLines( params string[] messages ) { + _lineItems = messages; + } + + IEnumerator< DisplayResponseLineDTO > IEnumerable< DisplayResponseLineDTO >.GetEnumerator() { + foreach ( string message in _lineItems ) { + yield return new DisplayResponseLineDTO( message ); + } + } + + public IEnumerator GetEnumerator() { + return ( ( IEnumerable< DisplayResponseLineDTO > )this ).GetEnumerator( ); + } + } +} \ No newline at end of file diff --git a/slips/src/app/Marina/Presentation/DTO/DockDisplayDTO.cs b/slips/src/app/Marina/Presentation/DTO/DockDisplayDTO.cs new file mode 100644 index 0000000..1a0e4d0 --- /dev/null +++ b/slips/src/app/Marina/Presentation/DTO/DockDisplayDTO.cs @@ -0,0 +1,36 @@ +using System; + +namespace Marina.Presentation.DTO { + [Serializable] + public class DockDisplayDTO { + private readonly string _name; + private readonly string _locationName; + private readonly string _waterService; + private readonly string _electricalService; + + private DockDisplayDTO() {} + + public DockDisplayDTO( string name, string locationName, string waterService, string electricalService ) { + _name = name; + _locationName = locationName; + _waterService = waterService; + _electricalService = electricalService; + } + + public string Name { + get { return _name; } + } + + public string LocationName { + get { return _locationName; } + } + + public string WaterService { + get { return _waterService; } + } + + public string ElectricalService { + get { return _electricalService; } + } + } +} \ No newline at end of file diff --git a/slips/src/app/Marina/Presentation/DTO/LoginCredentialsDTO.cs b/slips/src/app/Marina/Presentation/DTO/LoginCredentialsDTO.cs new file mode 100644 index 0000000..33365c1 --- /dev/null +++ b/slips/src/app/Marina/Presentation/DTO/LoginCredentialsDTO.cs @@ -0,0 +1,24 @@ +using System; + +namespace Marina.Presentation.DTO { + [Serializable] + public class LoginCredentialsDTO { + private readonly string username; + private readonly string password; + + private LoginCredentialsDTO() {} + + public LoginCredentialsDTO( string username, string password ) { + this.username = username; + this.password = password; + } + + public string Username { + get { return username; } + } + + public string Password { + get { return password; } + } + } +} \ No newline at end of file diff --git a/slips/src/app/Marina/Presentation/DTO/RegisterCustomerDTO.cs b/slips/src/app/Marina/Presentation/DTO/RegisterCustomerDTO.cs new file mode 100644 index 0000000..339572e --- /dev/null +++ b/slips/src/app/Marina/Presentation/DTO/RegisterCustomerDTO.cs @@ -0,0 +1,47 @@ +using System; + +namespace Marina.Presentation.DTO { + [Serializable] + public class RegisterCustomerDTO { + public RegisterCustomerDTO( string userName, string password, string firstName, string lastName, string phone, + string city ) { + _userName = userName; + _password = password; + _firstName = firstName; + _lastName = lastName; + _phone = phone; + _city = city; + } + + public string UserName { + get { return _userName; } + } + + public string Password { + get { return _password; } + } + + public string FirstName { + get { return _firstName; } + } + + public string LastName { + get { return _lastName; } + } + + public string Phone { + get { return _phone; } + } + + public string City { + get { return _city; } + } + + private string _userName; + private string _password; + private string _firstName; + private string _lastName; + private string _phone; + private string _city; + } +} \ No newline at end of file diff --git a/slips/src/app/Marina/Presentation/DTO/SlipDisplayDTO.cs b/slips/src/app/Marina/Presentation/DTO/SlipDisplayDTO.cs new file mode 100644 index 0000000..59267e4 --- /dev/null +++ b/slips/src/app/Marina/Presentation/DTO/SlipDisplayDTO.cs @@ -0,0 +1,48 @@ +using System; + +namespace Marina.Presentation.DTO { + [Serializable] + public class SlipDisplayDTO { + private SlipDisplayDTO() {} + + public SlipDisplayDTO( string dockId, string dockName, string width, string length, string locationName, string slipId ) { + _dockName = dockName; + _slipId = slipId; + _locationName = locationName; + _dockId = dockId; + _width = width; + _length = length; + } + + public string DockName { + get { return _dockName; } + } + + public string Width { + get { return _width; } + } + + public string Length { + get { return _length; } + } + + public string DockId { + get { return _dockId; } + } + + public string LocationName { + get { return _locationName; } + } + + public string SlipId { + get { return _slipId; } + } + + private string _dockName; + private string _width; + private string _length; + private string _dockId; + private string _locationName; + private string _slipId; + } +} \ No newline at end of file diff --git a/slips/src/app/Marina/Presentation/DTO/SubmitLeaseRequestDTO.cs b/slips/src/app/Marina/Presentation/DTO/SubmitLeaseRequestDTO.cs new file mode 100644 index 0000000..a7899b1 --- /dev/null +++ b/slips/src/app/Marina/Presentation/DTO/SubmitLeaseRequestDTO.cs @@ -0,0 +1,60 @@ +using System; + +namespace Marina.Presentation.DTO { + [Serializable] + public class SubmitLeaseRequestDTO : IEquatable< SubmitLeaseRequestDTO > { + private SubmitLeaseRequestDTO() {} + + public SubmitLeaseRequestDTO( long customerId, long slipId, string duration ) { + _customerId = customerId; + _slipId = slipId; + _duration = duration; + } + + public long CustomerId { + get { return _customerId; } + } + + public long SlipId { + get { return _slipId; } + } + + public string Duration { + get { return _duration; } + } + + public bool Equals( SubmitLeaseRequestDTO submitLeaseRequestDTO ) { + if ( submitLeaseRequestDTO == null ) { + return false; + } + if ( _customerId != submitLeaseRequestDTO._customerId ) { + return false; + } + if ( _slipId != submitLeaseRequestDTO._slipId ) { + return false; + } + if ( !Equals( _duration, submitLeaseRequestDTO._duration ) ) { + return false; + } + return true; + } + + public override bool Equals( object obj ) { + if ( ReferenceEquals( this, obj ) ) { + return true; + } + return Equals( obj as SubmitLeaseRequestDTO ); + } + + public override int GetHashCode() { + int result = ( int )_customerId; + result = 29*result + ( int )_slipId; + result = 29*result + ( _duration != null ? _duration.GetHashCode( ) : 0 ); + return result; + } + + private readonly long _customerId; + private readonly long _slipId; + private readonly string _duration; + } +} \ No newline at end of file diff --git a/slips/src/app/Marina/Presentation/DTO/UpdateCustomerRegistrationDTO.cs b/slips/src/app/Marina/Presentation/DTO/UpdateCustomerRegistrationDTO.cs new file mode 100644 index 0000000..8f4681a --- /dev/null +++ b/slips/src/app/Marina/Presentation/DTO/UpdateCustomerRegistrationDTO.cs @@ -0,0 +1,53 @@ +using System; + +namespace Marina.Presentation.DTO { + [Serializable] + public class UpdateCustomerRegistrationDTO { + private long customerId; + private string username; + private string password; + private string firstName; + private string lastName; + private string phoneNumber; + private string city; + + public UpdateCustomerRegistrationDTO( long customerId, string username, string password, string firstName, + string lastName, string phoneNumber, string city ) { + this.customerId = customerId; + this.username = username; + this.password = password; + this.firstName = firstName; + this.lastName = lastName; + this.phoneNumber = phoneNumber; + this.city = city; + } + + public long CustomerId { + get { return customerId; } + } + + public string Username { + get { return username; } + } + + public string Password { + get { return password; } + } + + public string FirstName { + get { return firstName; } + } + + public string LastName { + get { return lastName; } + } + + public string PhoneNumber { + get { return phoneNumber; } + } + + public string City { + get { return city; } + } + } +} \ No newline at end of file diff --git a/slips/src/app/Marina/Presentation/Mappers/CustomerRegistrationPresentationMapper.cs b/slips/src/app/Marina/Presentation/Mappers/CustomerRegistrationPresentationMapper.cs new file mode 100644 index 0000000..9d70078 --- /dev/null +++ b/slips/src/app/Marina/Presentation/Mappers/CustomerRegistrationPresentationMapper.cs @@ -0,0 +1,17 @@ +using Marina.Presentation.DTO; +using Marina.Presentation.Views; + +namespace Marina.Presentation.Mappers { + public class CustomerRegistrationPresentationMapper : ICustomerRegistrationPresentationMapper { + public RegisterCustomerDTO MapFrom( ICustomerRegistrationView view ) { + return new RegisterCustomerDTO( + view.UserName( ), + view.Password( ), + view.FirstName( ), + view.LastName( ), + view.PhoneNumber( ), + view.City( ) + ); + } + } +} \ No newline at end of file diff --git a/slips/src/app/Marina/Presentation/Mappers/ICustomerRegistrationPresentationMapper.cs b/slips/src/app/Marina/Presentation/Mappers/ICustomerRegistrationPresentationMapper.cs new file mode 100644 index 0000000..e39373b --- /dev/null +++ b/slips/src/app/Marina/Presentation/Mappers/ICustomerRegistrationPresentationMapper.cs @@ -0,0 +1,8 @@ +using Marina.Infrastructure; +using Marina.Presentation.DTO; +using Marina.Presentation.Views; + +namespace Marina.Presentation.Mappers { + public interface ICustomerRegistrationPresentationMapper : + IMapper< ICustomerRegistrationView, RegisterCustomerDTO > {} +} \ No newline at end of file diff --git a/slips/src/app/Marina/Presentation/Mappers/ILeaseRequestDtoFromHttpRequestMapper.cs b/slips/src/app/Marina/Presentation/Mappers/ILeaseRequestDtoFromHttpRequestMapper.cs new file mode 100644 index 0000000..720019c --- /dev/null +++ b/slips/src/app/Marina/Presentation/Mappers/ILeaseRequestDtoFromHttpRequestMapper.cs @@ -0,0 +1,7 @@ +using Marina.Infrastructure; +using Marina.Presentation.DTO; +using Marina.Web; + +namespace Marina.Presentation.Mappers { + public interface ILeaseRequestDtoFromHttpRequestMapper : IMapper< IHttpRequest, SubmitLeaseRequestDTO > {} +} \ No newline at end of file diff --git a/slips/src/app/Marina/Presentation/Mappers/ILoginCredentialsMapper.cs b/slips/src/app/Marina/Presentation/Mappers/ILoginCredentialsMapper.cs new file mode 100644 index 0000000..aac8f81 --- /dev/null +++ b/slips/src/app/Marina/Presentation/Mappers/ILoginCredentialsMapper.cs @@ -0,0 +1,7 @@ +using Marina.Infrastructure; +using Marina.Presentation.DTO; +using Marina.Web; + +namespace Marina.Presentation.Mappers { + public interface ILoginCredentialsMapper : IMapper< IHttpRequest, LoginCredentialsDTO > {} +} \ No newline at end of file diff --git a/slips/src/app/Marina/Presentation/Mappers/INewBoatRegistrationMapper.cs b/slips/src/app/Marina/Presentation/Mappers/INewBoatRegistrationMapper.cs new file mode 100644 index 0000000..8e115af --- /dev/null +++ b/slips/src/app/Marina/Presentation/Mappers/INewBoatRegistrationMapper.cs @@ -0,0 +1,7 @@ +using Marina.Infrastructure; +using Marina.Presentation.DTO; +using Marina.Web; + +namespace Marina.Presentation.Mappers { + public interface INewBoatRegistrationMapper : IMapper< IHttpRequest, BoatRegistrationDTO > {} +} \ No newline at end of file diff --git a/slips/src/app/Marina/Presentation/Mappers/IUpdateRegistrationPresentationMapper.cs b/slips/src/app/Marina/Presentation/Mappers/IUpdateRegistrationPresentationMapper.cs new file mode 100644 index 0000000..0c63fd7 --- /dev/null +++ b/slips/src/app/Marina/Presentation/Mappers/IUpdateRegistrationPresentationMapper.cs @@ -0,0 +1,7 @@ +using Marina.Infrastructure; +using Marina.Presentation.DTO; +using Marina.Web; + +namespace Marina.Presentation.Mappers { + public interface IUpdateRegistrationPresentationMapper : IMapper< IHttpRequest, UpdateCustomerRegistrationDTO > {} +} \ No newline at end of file diff --git a/slips/src/app/Marina/Presentation/Mappers/LeaseRequestDtoFromHttpRequestMapper.cs b/slips/src/app/Marina/Presentation/Mappers/LeaseRequestDtoFromHttpRequestMapper.cs new file mode 100644 index 0000000..ed5bbc6 --- /dev/null +++ b/slips/src/app/Marina/Presentation/Mappers/LeaseRequestDtoFromHttpRequestMapper.cs @@ -0,0 +1,14 @@ +using Marina.Presentation.DTO; +using Marina.Web; + +namespace Marina.Presentation.Mappers { + public class LeaseRequestDtoFromHttpRequestMapper : ILeaseRequestDtoFromHttpRequestMapper { + public SubmitLeaseRequestDTO MapFrom( IHttpRequest input ) { + return new SubmitLeaseRequestDTO( + input.ParsePayloadFor( PayloadKeys.CustomerId ), + input.ParsePayloadFor( PayloadKeys.SlipId ), + input.ParsePayloadFor( PayloadKeys.For( "uxLeaseDuration" ) ) + ); + } + } +} \ No newline at end of file diff --git a/slips/src/app/Marina/Presentation/Mappers/LoginCredentialsMapper.cs b/slips/src/app/Marina/Presentation/Mappers/LoginCredentialsMapper.cs new file mode 100644 index 0000000..9e13c13 --- /dev/null +++ b/slips/src/app/Marina/Presentation/Mappers/LoginCredentialsMapper.cs @@ -0,0 +1,13 @@ +using Marina.Presentation.DTO; +using Marina.Web; + +namespace Marina.Presentation.Mappers { + public class LoginCredentialsMapper : ILoginCredentialsMapper { + public LoginCredentialsDTO MapFrom( IHttpRequest input ) { + return new LoginCredentialsDTO( + input.ParsePayloadFor( PayloadKeys.For( "uxUserNameTextBox" ) ), + input.ParsePayloadFor( PayloadKeys.For( "uxPasswordTextBox" ) ) + ); + } + } +} \ No newline at end of file diff --git a/slips/src/app/Marina/Presentation/Mappers/NewBoatRegistrationMapper.cs b/slips/src/app/Marina/Presentation/Mappers/NewBoatRegistrationMapper.cs new file mode 100644 index 0000000..d815e6d --- /dev/null +++ b/slips/src/app/Marina/Presentation/Mappers/NewBoatRegistrationMapper.cs @@ -0,0 +1,16 @@ +using Marina.Presentation.DTO; +using Marina.Web; + +namespace Marina.Presentation.Mappers { + public class NewBoatRegistrationMapper : INewBoatRegistrationMapper { + public BoatRegistrationDTO MapFrom( IHttpRequest input ) { + return new BoatRegistrationDTO( + input.ParsePayloadFor( PayloadKeys.For( "uxRegistrationNumberTextBox" ) ), + input.ParsePayloadFor( PayloadKeys.For( "uxManufacturerTextBox" ) ), + input.ParsePayloadFor( PayloadKeys.For( "uxModelYearTextBox" ) ), + input.ParsePayloadFor( PayloadKeys.For( "uxLengthTextBox" ) ), + input.ParsePayloadFor( PayloadKeys.CustomerId ) + ); + } + } +} \ No newline at end of file diff --git a/slips/src/app/Marina/Presentation/Mappers/UpdateRegistrationPresentationMapper.cs b/slips/src/app/Marina/Presentation/Mappers/UpdateRegistrationPresentationMapper.cs new file mode 100644 index 0000000..814fde5 --- /dev/null +++ b/slips/src/app/Marina/Presentation/Mappers/UpdateRegistrationPresentationMapper.cs @@ -0,0 +1,18 @@ +using Marina.Presentation.DTO; +using Marina.Web; + +namespace Marina.Presentation.Mappers { + public class UpdateRegistrationPresentationMapper : IUpdateRegistrationPresentationMapper { + public UpdateCustomerRegistrationDTO MapFrom( IHttpRequest input ) { + return new UpdateCustomerRegistrationDTO( + input.ParsePayloadFor( PayloadKeys.CustomerId ), + input.ParsePayloadFor( PayloadKeys.For( "uxUserNameTextBox" ) ), + input.ParsePayloadFor( PayloadKeys.For( "uxPasswordTextBox" ) ), + input.ParsePayloadFor( PayloadKeys.For( "uxFirstNameTextBox" ) ), + input.ParsePayloadFor( PayloadKeys.For( "uxLastNameTextBox" ) ), + input.ParsePayloadFor( PayloadKeys.For( "uxPhoneNumberTextBox" ) ), + input.ParsePayloadFor( PayloadKeys.For( "uxCityTextBox" ) ) + ); + } + } +} \ No newline at end of file diff --git a/slips/src/app/Marina/Presentation/PayLoadKeys.cs b/slips/src/app/Marina/Presentation/PayLoadKeys.cs new file mode 100644 index 0000000..6d91a96 --- /dev/null +++ b/slips/src/app/Marina/Presentation/PayLoadKeys.cs @@ -0,0 +1,12 @@ +namespace Marina.Presentation { + public class PayloadKeys { + public static PayloadKey< long > DockId = new PayloadKey< long >( "DID" ); + public static PayloadKey< long > LocationId = new PayloadKey< long >( "LID" ); + public static PayloadKey< long > CustomerId = new PayloadKey< long >( "CID" ); + public static PayloadKey< long > SlipId = new PayloadKey< long >( "SID" ); + + public static PayloadKey< string > For( string controlId ) { + return new PayloadKey< string >( controlId ); + } + } +} \ No newline at end of file diff --git a/slips/src/app/Marina/Presentation/PayloadKey.cs b/slips/src/app/Marina/Presentation/PayloadKey.cs new file mode 100644 index 0000000..d4b31fb --- /dev/null +++ b/slips/src/app/Marina/Presentation/PayloadKey.cs @@ -0,0 +1,48 @@ +using System; +using System.Collections.Specialized; + +namespace Marina.Presentation +{ + public class PayloadKey< T > : IEquatable< PayloadKey< T > > + { + private readonly string _key; + + public PayloadKey( string key ) + { + _key = key; + } + + public T ParseFrom( NameValueCollection payload ) + { + EnsureKeyIsInPayload( payload ); + return ( T )Convert.ChangeType( payload[ _key ], typeof( T ) ); + } + + private void EnsureKeyIsInPayload( NameValueCollection payload ) + { + if( null == payload[ _key ] ) { + throw new PayloadKeyNotFoundException( _key ); + } + } + + public static implicit operator string( PayloadKey< T > item ) + { + return item._key; + } + + public bool Equals( PayloadKey< T > payloadKey ) + { + return payloadKey != null && Equals( _key, payloadKey._key ); + } + + public override bool Equals( object obj ) + { + return ReferenceEquals( this, obj ) || Equals( obj as PayloadKey< T > ); + } + + public override int GetHashCode( ) + { + return _key.GetHashCode( ); + } + } +} \ No newline at end of file diff --git a/slips/src/app/Marina/Presentation/PayloadKeyNotFoundException.cs b/slips/src/app/Marina/Presentation/PayloadKeyNotFoundException.cs new file mode 100644 index 0000000..5cf4279 --- /dev/null +++ b/slips/src/app/Marina/Presentation/PayloadKeyNotFoundException.cs @@ -0,0 +1,7 @@ +using System; + +namespace Marina.Presentation { + public class PayloadKeyNotFoundException : Exception { + public PayloadKeyNotFoundException( string key ) : base( "The payload key could not be found: " + key ) {} + } +} \ No newline at end of file diff --git a/slips/src/app/Marina/Presentation/Presenters/AvailableSlipsPresenter.cs b/slips/src/app/Marina/Presentation/Presenters/AvailableSlipsPresenter.cs new file mode 100644 index 0000000..9dbe7f5 --- /dev/null +++ b/slips/src/app/Marina/Presentation/Presenters/AvailableSlipsPresenter.cs @@ -0,0 +1,25 @@ +using Marina.Infrastructure.Container; +using Marina.Presentation.Views; +using Marina.Task; + +namespace Marina.Presentation.Presenters { + public class AvailableSlipsPresenter : IAvailableSlipsPresenter { + private readonly IAvailableSlipsView view; + private readonly ICatalogTasks task; + + public AvailableSlipsPresenter( IAvailableSlipsView view ) + : this( + view, + Resolve.DependencyFor< ICatalogTasks >( ) + ) {} + + public AvailableSlipsPresenter( IAvailableSlipsView view, ICatalogTasks task ) { + this.view = view; + this.task = task; + } + + public void Initialize() { + view.Display( task.GetAllAvailableSlips( ) ); + } + } +} \ No newline at end of file diff --git a/slips/src/app/Marina/Presentation/Presenters/CurrentLeasesPresenter.cs b/slips/src/app/Marina/Presentation/Presenters/CurrentLeasesPresenter.cs new file mode 100644 index 0000000..7f80cc4 --- /dev/null +++ b/slips/src/app/Marina/Presentation/Presenters/CurrentLeasesPresenter.cs @@ -0,0 +1,25 @@ +using Marina.Infrastructure.Container; +using Marina.Presentation.Views; +using Marina.Task; +using Marina.Web; + +namespace Marina.Presentation.Presenters { + public class CurrentLeasesPresenter : ICurrentLeasesPresenter { + public CurrentLeasesPresenter( ICurrentLeasesView view ) + : this( view, Resolve.DependencyFor< IHttpRequest >( ), Resolve.DependencyFor< ILeaseTasks >( ) ) {} + + public CurrentLeasesPresenter( ICurrentLeasesView view, IHttpRequest request, ILeaseTasks task ) { + _view = view; + _request = request; + _task = task; + } + + public void Initialize() { + _view.Display( _task.FindAllLeasesFor( _request.ParsePayloadFor( PayloadKeys.CustomerId ) ) ); + } + + private readonly ICurrentLeasesView _view; + private readonly IHttpRequest _request; + private readonly ILeaseTasks _task; + } +} \ No newline at end of file diff --git a/slips/src/app/Marina/Presentation/Presenters/CustomerRegistrationPresenter.cs b/slips/src/app/Marina/Presentation/Presenters/CustomerRegistrationPresenter.cs new file mode 100644 index 0000000..ea9ff8d --- /dev/null +++ b/slips/src/app/Marina/Presentation/Presenters/CustomerRegistrationPresenter.cs @@ -0,0 +1,30 @@ +using Marina.Infrastructure.Container; +using Marina.Presentation.Mappers; +using Marina.Presentation.Views; +using Marina.Task; + +namespace Marina.Presentation.Presenters { + public class CustomerRegistrationPresenter : ICustomerRegistrationPresenter { + private readonly ICustomerRegistrationView _view; + private readonly ICustomerRegistrationPresentationMapper _mapper; + private readonly IRegistrationTasks _task; + + public CustomerRegistrationPresenter( ICustomerRegistrationView view ) : this( + view, + Resolve.DependencyFor< ICustomerRegistrationPresentationMapper >( ), + Resolve.DependencyFor< IRegistrationTasks >( ) + ) {} + + public CustomerRegistrationPresenter( ICustomerRegistrationView view, + ICustomerRegistrationPresentationMapper mapper, + IRegistrationTasks task ) { + _view = view; + _mapper = mapper; + _task = task; + } + + public void RegisterCustomer( ) { + _view.Display( _task.RegisterNew( _mapper.MapFrom( _view ) ) ); + } + } +} \ No newline at end of file diff --git a/slips/src/app/Marina/Presentation/Presenters/DockPresenter.cs b/slips/src/app/Marina/Presentation/Presenters/DockPresenter.cs new file mode 100644 index 0000000..4eb9402 --- /dev/null +++ b/slips/src/app/Marina/Presentation/Presenters/DockPresenter.cs @@ -0,0 +1,31 @@ +using Marina.Infrastructure.Container; +using Marina.Presentation.Views; +using Marina.Task; +using Marina.Web; + +namespace Marina.Presentation.Presenters { + public class DockPresenter : IDockPresenter { + public DockPresenter( IDockView view ) + : this( + view, + Resolve.DependencyFor< IHttpRequest >( ), + Resolve.DependencyFor< ICatalogTasks >( ) + ) {} + + public DockPresenter( IDockView view, IHttpRequest request, ICatalogTasks task ) { + _request = request; + _view = view; + _task = task; + } + + public void Initialize() { + long dockId = _request.ParsePayloadFor( PayloadKeys.DockId ); + _view.Display( _task.GetDockInformationBy( dockId ) ); + _view.Display( _task.GetAvailableSlipsForDockBy( dockId ) ); + } + + private readonly IDockView _view; + private readonly ICatalogTasks _task; + private readonly IHttpRequest _request; + } +} \ No newline at end of file diff --git a/slips/src/app/Marina/Presentation/Presenters/IAvailableSlipsPresenter.cs b/slips/src/app/Marina/Presentation/Presenters/IAvailableSlipsPresenter.cs new file mode 100644 index 0000000..38d4dd3 --- /dev/null +++ b/slips/src/app/Marina/Presentation/Presenters/IAvailableSlipsPresenter.cs @@ -0,0 +1,5 @@ +namespace Marina.Presentation.Presenters { + public interface IAvailableSlipsPresenter { + void Initialize( ); + } +} \ No newline at end of file diff --git a/slips/src/app/Marina/Presentation/Presenters/ICurrentLeasesPresenter.cs b/slips/src/app/Marina/Presentation/Presenters/ICurrentLeasesPresenter.cs new file mode 100644 index 0000000..e5c0efb --- /dev/null +++ b/slips/src/app/Marina/Presentation/Presenters/ICurrentLeasesPresenter.cs @@ -0,0 +1,5 @@ +namespace Marina.Presentation.Presenters { + public interface ICurrentLeasesPresenter { + void Initialize(); + } +} \ No newline at end of file diff --git a/slips/src/app/Marina/Presentation/Presenters/ICustomerRegistrationPresenter.cs b/slips/src/app/Marina/Presentation/Presenters/ICustomerRegistrationPresenter.cs new file mode 100644 index 0000000..7089c7f --- /dev/null +++ b/slips/src/app/Marina/Presentation/Presenters/ICustomerRegistrationPresenter.cs @@ -0,0 +1,5 @@ +namespace Marina.Presentation.Presenters { + public interface ICustomerRegistrationPresenter { + void RegisterCustomer( ); + } +} \ No newline at end of file diff --git a/slips/src/app/Marina/Presentation/Presenters/IDockPresenter.cs b/slips/src/app/Marina/Presentation/Presenters/IDockPresenter.cs new file mode 100644 index 0000000..fb250d2 --- /dev/null +++ b/slips/src/app/Marina/Presentation/Presenters/IDockPresenter.cs @@ -0,0 +1,5 @@ +namespace Marina.Presentation.Presenters { + public interface IDockPresenter { + void Initialize( ); + } +} \ No newline at end of file diff --git a/slips/src/app/Marina/Presentation/Presenters/ILeaseSlipPresenter.cs b/slips/src/app/Marina/Presentation/Presenters/ILeaseSlipPresenter.cs new file mode 100644 index 0000000..4908743 --- /dev/null +++ b/slips/src/app/Marina/Presentation/Presenters/ILeaseSlipPresenter.cs @@ -0,0 +1,7 @@ +namespace Marina.Presentation.Presenters { + public interface ILeaseSlipPresenter { + void Initialize(); + + void SubmitLeaseRequest(); + } +} \ No newline at end of file diff --git a/slips/src/app/Marina/Presentation/Presenters/ILoginPresenter.cs b/slips/src/app/Marina/Presentation/Presenters/ILoginPresenter.cs new file mode 100644 index 0000000..554ef98 --- /dev/null +++ b/slips/src/app/Marina/Presentation/Presenters/ILoginPresenter.cs @@ -0,0 +1,5 @@ +namespace Marina.Presentation.Presenters { + public interface ILoginPresenter { + void Login( ); + } +} \ No newline at end of file diff --git a/slips/src/app/Marina/Presentation/Presenters/IRegisterBoatPresenter.cs b/slips/src/app/Marina/Presentation/Presenters/IRegisterBoatPresenter.cs new file mode 100644 index 0000000..37f558f --- /dev/null +++ b/slips/src/app/Marina/Presentation/Presenters/IRegisterBoatPresenter.cs @@ -0,0 +1,5 @@ +namespace Marina.Presentation.Presenters { + public interface IRegisterBoatPresenter { + void SubmitRegistration( ); + } +} \ No newline at end of file diff --git a/slips/src/app/Marina/Presentation/Presenters/IUpdateCustomerRegistrationPresenter.cs b/slips/src/app/Marina/Presentation/Presenters/IUpdateCustomerRegistrationPresenter.cs new file mode 100644 index 0000000..f74171c --- /dev/null +++ b/slips/src/app/Marina/Presentation/Presenters/IUpdateCustomerRegistrationPresenter.cs @@ -0,0 +1,7 @@ +namespace Marina.Presentation.Presenters { + public interface IUpdateCustomerRegistrationPresenter { + void Initialize( ); + + void UpdateRegistration( ); + } +} \ No newline at end of file diff --git a/slips/src/app/Marina/Presentation/Presenters/IViewRegisteredBoatsPresenter.cs b/slips/src/app/Marina/Presentation/Presenters/IViewRegisteredBoatsPresenter.cs new file mode 100644 index 0000000..4bee850 --- /dev/null +++ b/slips/src/app/Marina/Presentation/Presenters/IViewRegisteredBoatsPresenter.cs @@ -0,0 +1,5 @@ +namespace Marina.Presentation.Presenters { + public interface IViewRegisteredBoatsPresenter { + void Initialize(); + } +} \ No newline at end of file diff --git a/slips/src/app/Marina/Presentation/Presenters/LeaseSlipPresenter.cs b/slips/src/app/Marina/Presentation/Presenters/LeaseSlipPresenter.cs new file mode 100644 index 0000000..e24441c --- /dev/null +++ b/slips/src/app/Marina/Presentation/Presenters/LeaseSlipPresenter.cs @@ -0,0 +1,41 @@ +using Marina.Infrastructure.Container; +using Marina.Presentation.Mappers; +using Marina.Presentation.Views; +using Marina.Task; +using Marina.Web; + +namespace Marina.Presentation.Presenters { + public class LeaseSlipPresenter : ILeaseSlipPresenter { + public LeaseSlipPresenter( ILeaseSlipView view ) + : this( + view, + Resolve.DependencyFor< IHttpRequest >( ), + Resolve.DependencyFor< ICatalogTasks >( ), + Resolve.DependencyFor< ILeaseTasks >( ), + Resolve.DependencyFor< ILeaseRequestDtoFromHttpRequestMapper >( ) + ) {} + + public LeaseSlipPresenter( ILeaseSlipView view, IHttpRequest request, ICatalogTasks task, ILeaseTasks leaseTask, + ILeaseRequestDtoFromHttpRequestMapper mapper ) { + _view = view; + _request = request; + _task = task; + _leaseTask = leaseTask; + _mapper = mapper; + } + + public void Initialize() { + _view.Display( _task.FindSlipBy( _request.ParsePayloadFor( PayloadKeys.SlipId ) ) ); + } + + public void SubmitLeaseRequest() { + _view.Display( _leaseTask.RequestLeaseUsing( _mapper.MapFrom( _request ) ) ); + } + + private readonly ILeaseSlipView _view; + private readonly IHttpRequest _request; + private readonly ICatalogTasks _task; + private readonly ILeaseTasks _leaseTask; + private readonly ILeaseRequestDtoFromHttpRequestMapper _mapper; + } +} \ No newline at end of file diff --git a/slips/src/app/Marina/Presentation/Presenters/LoginPresenter.cs b/slips/src/app/Marina/Presentation/Presenters/LoginPresenter.cs new file mode 100644 index 0000000..94ae726 --- /dev/null +++ b/slips/src/app/Marina/Presentation/Presenters/LoginPresenter.cs @@ -0,0 +1,34 @@ +using Marina.Infrastructure.Container; +using Marina.Presentation.Mappers; +using Marina.Presentation.Views; +using Marina.Task; +using Marina.Web; + +namespace Marina.Presentation.Presenters { + public class LoginPresenter : ILoginPresenter { + public LoginPresenter( ILoginView view ) + : this( + view, + Resolve.DependencyFor< IHttpRequest >( ), + Resolve.DependencyFor< IAuthenticationTask >( ), + Resolve.DependencyFor< ILoginCredentialsMapper >( ) + ) {} + + public LoginPresenter( ILoginView view, IHttpRequest request, IAuthenticationTask task, + ILoginCredentialsMapper mapper ) { + _view = view; + _request = request; + _task = task; + _mapper = mapper; + } + + public void Login() { + _view.Display( _task.AuthenticateUserUsing( _mapper.MapFrom( _request ) ) ); + } + + private readonly ILoginView _view; + private readonly IHttpRequest _request; + private readonly IAuthenticationTask _task; + private readonly ILoginCredentialsMapper _mapper; + } +} \ No newline at end of file diff --git a/slips/src/app/Marina/Presentation/Presenters/RegisterBoatPresenter.cs b/slips/src/app/Marina/Presentation/Presenters/RegisterBoatPresenter.cs new file mode 100644 index 0000000..693c1ff --- /dev/null +++ b/slips/src/app/Marina/Presentation/Presenters/RegisterBoatPresenter.cs @@ -0,0 +1,33 @@ +using Marina.Infrastructure.Container; +using Marina.Presentation.Mappers; +using Marina.Presentation.Views; +using Marina.Task; +using Marina.Web; + +namespace Marina.Presentation.Presenters { + public class RegisterBoatPresenter : IRegisterBoatPresenter { + public RegisterBoatPresenter( IRegisterBoatView view ) + : this( view, + Resolve.DependencyFor< IHttpRequest >( ), + Resolve.DependencyFor< IRegistrationTasks >( ), + Resolve.DependencyFor< INewBoatRegistrationMapper >( ) + ) {} + + public RegisterBoatPresenter( IRegisterBoatView view, IHttpRequest request, IRegistrationTasks task, + INewBoatRegistrationMapper mapper ) { + _view = view; + _request = request; + _task = task; + _mapper = mapper; + } + + public void SubmitRegistration() { + _view.Display( _task.AddNewBoatUsing( _mapper.MapFrom( _request ) ) ); + } + + private readonly IRegisterBoatView _view; + private readonly IHttpRequest _request; + private readonly IRegistrationTasks _task; + private readonly INewBoatRegistrationMapper _mapper; + } +} \ No newline at end of file diff --git a/slips/src/app/Marina/Presentation/Presenters/UpdateCustomerRegistrationPresenter.cs b/slips/src/app/Marina/Presentation/Presenters/UpdateCustomerRegistrationPresenter.cs new file mode 100644 index 0000000..8a4047f --- /dev/null +++ b/slips/src/app/Marina/Presentation/Presenters/UpdateCustomerRegistrationPresenter.cs @@ -0,0 +1,44 @@ +using Marina.Infrastructure.Container; +using Marina.Presentation.Mappers; +using Marina.Presentation.Views; +using Marina.Task; +using Marina.Web; + +namespace Marina.Presentation.Presenters { + public class UpdateCustomerRegistrationPresenter : IUpdateCustomerRegistrationPresenter { + public UpdateCustomerRegistrationPresenter( IUpdateRegistrationView view ) : + this( + view, + Resolve.DependencyFor< IHttpRequest >( ), + Resolve.DependencyFor< IRegistrationTasks >( ), + Resolve.DependencyFor< IUpdateRegistrationPresentationMapper >( ) + ) {} + + public UpdateCustomerRegistrationPresenter( IUpdateRegistrationView view, IHttpRequest request, + IRegistrationTasks task, + IUpdateRegistrationPresentationMapper mapper ) { + _request = request; + _view = view; + _task = task; + _mapper = mapper; + } + + public void Initialize() { + _view.Display( _task.LoadRegistrationFor( CustomerId( ) ) ); + } + + public void UpdateRegistration() { + _view.Display( _task.UpdateRegistrationFor( _mapper.MapFrom( _request ) ) ); + Initialize( ); + } + + private long CustomerId() { + return _request.ParsePayloadFor( PayloadKeys.CustomerId ); + } + + private readonly IUpdateRegistrationView _view; + private readonly IRegistrationTasks _task; + private readonly IUpdateRegistrationPresentationMapper _mapper; + private readonly IHttpRequest _request; + } +} \ No newline at end of file diff --git a/slips/src/app/Marina/Presentation/Presenters/ViewRegisteredBoatsPresenter.cs b/slips/src/app/Marina/Presentation/Presenters/ViewRegisteredBoatsPresenter.cs new file mode 100644 index 0000000..6728c01 --- /dev/null +++ b/slips/src/app/Marina/Presentation/Presenters/ViewRegisteredBoatsPresenter.cs @@ -0,0 +1,25 @@ +using Marina.Infrastructure.Container; +using Marina.Presentation.Views; +using Marina.Task; +using Marina.Web; + +namespace Marina.Presentation.Presenters { + public class ViewRegisteredBoatsPresenter : IViewRegisteredBoatsPresenter { + public ViewRegisteredBoatsPresenter( IRegisteredBoatsView view ) + : this( view, Resolve.DependencyFor< IRegistrationTasks >( ), Resolve.DependencyFor< IHttpRequest >( ) ) {} + + public ViewRegisteredBoatsPresenter( IRegisteredBoatsView view, IRegistrationTasks task, IHttpRequest request ) { + _view = view; + _task = task; + _request = request; + } + + public void Initialize() { + _view.Display( _task.AllBoatsFor( _request.ParsePayloadFor( PayloadKeys.CustomerId ) ) ); + } + + private readonly IRegisteredBoatsView _view; + private readonly IRegistrationTasks _task; + private readonly IHttpRequest _request; + } +} \ No newline at end of file diff --git a/slips/src/app/Marina/Presentation/Views/IAvailableSlipsView.cs b/slips/src/app/Marina/Presentation/Views/IAvailableSlipsView.cs new file mode 100644 index 0000000..c421e91 --- /dev/null +++ b/slips/src/app/Marina/Presentation/Views/IAvailableSlipsView.cs @@ -0,0 +1,8 @@ +using System.Collections.Generic; +using Marina.Presentation.DTO; + +namespace Marina.Presentation.Views { + public interface IAvailableSlipsView { + void Display( IEnumerable< SlipDisplayDTO > availableSlips ); + } +} \ No newline at end of file diff --git a/slips/src/app/Marina/Presentation/Views/ICurrentLeasesView.cs b/slips/src/app/Marina/Presentation/Views/ICurrentLeasesView.cs new file mode 100644 index 0000000..682dfe5 --- /dev/null +++ b/slips/src/app/Marina/Presentation/Views/ICurrentLeasesView.cs @@ -0,0 +1,8 @@ +using System.Collections.Generic; +using Marina.Presentation.DTO; + +namespace Marina.Presentation.Views { + public interface ICurrentLeasesView { + void Display( IEnumerable< DisplayLeaseDTO > leases ); + } +} \ No newline at end of file diff --git a/slips/src/app/Marina/Presentation/Views/ICustomerRegistrationView.cs b/slips/src/app/Marina/Presentation/Views/ICustomerRegistrationView.cs new file mode 100644 index 0000000..be50275 --- /dev/null +++ b/slips/src/app/Marina/Presentation/Views/ICustomerRegistrationView.cs @@ -0,0 +1,20 @@ +using System.Collections.Generic; +using Marina.Presentation.DTO; + +namespace Marina.Presentation.Views { + public interface ICustomerRegistrationView { + string UserName( ); + + string Password( ); + + string FirstName( ); + + string LastName( ); + + string PhoneNumber( ); + + string City( ); + + void Display( IEnumerable< DisplayResponseLineDTO > response ); + } +} \ No newline at end of file diff --git a/slips/src/app/Marina/Presentation/Views/IDockView.cs b/slips/src/app/Marina/Presentation/Views/IDockView.cs new file mode 100644 index 0000000..975248c --- /dev/null +++ b/slips/src/app/Marina/Presentation/Views/IDockView.cs @@ -0,0 +1,9 @@ +using System.Collections.Generic; +using Marina.Presentation.DTO; + +namespace Marina.Presentation.Views { + public interface IDockView { + void Display( DockDisplayDTO dto ); + void Display( IEnumerable< SlipDisplayDTO > availableSlips ); + } +} \ No newline at end of file diff --git a/slips/src/app/Marina/Presentation/Views/ILeaseSlipView.cs b/slips/src/app/Marina/Presentation/Views/ILeaseSlipView.cs new file mode 100644 index 0000000..2751a54 --- /dev/null +++ b/slips/src/app/Marina/Presentation/Views/ILeaseSlipView.cs @@ -0,0 +1,9 @@ +using Marina.Presentation.DTO; + +namespace Marina.Presentation.Views { + public interface ILeaseSlipView { + void Display( SlipDisplayDTO slip ); + + void Display( DisplayResponseLineDTO response ); + } +} \ No newline at end of file diff --git a/slips/src/app/Marina/Presentation/Views/ILoginView.cs b/slips/src/app/Marina/Presentation/Views/ILoginView.cs new file mode 100644 index 0000000..b5d7c8f --- /dev/null +++ b/slips/src/app/Marina/Presentation/Views/ILoginView.cs @@ -0,0 +1,7 @@ +using Marina.Presentation.DTO; + +namespace Marina.Presentation.Views { + public interface ILoginView { + void Display( DisplayResponseLineDTO responseMessage ); + } +} \ No newline at end of file diff --git a/slips/src/app/Marina/Presentation/Views/IRegisterBoatView.cs b/slips/src/app/Marina/Presentation/Views/IRegisterBoatView.cs new file mode 100644 index 0000000..42559b7 --- /dev/null +++ b/slips/src/app/Marina/Presentation/Views/IRegisterBoatView.cs @@ -0,0 +1,8 @@ +using System.Collections.Generic; +using Marina.Presentation.DTO; + +namespace Marina.Presentation.Views { + public interface IRegisterBoatView { + void Display( IEnumerable< DisplayResponseLineDTO > response ); + } +} \ No newline at end of file diff --git a/slips/src/app/Marina/Presentation/Views/IRegisteredBoatsView.cs b/slips/src/app/Marina/Presentation/Views/IRegisteredBoatsView.cs new file mode 100644 index 0000000..9162695 --- /dev/null +++ b/slips/src/app/Marina/Presentation/Views/IRegisteredBoatsView.cs @@ -0,0 +1,8 @@ +using System.Collections.Generic; +using Marina.Presentation.DTO; + +namespace Marina.Presentation.Views { + public interface IRegisteredBoatsView { + void Display( IEnumerable< BoatRegistrationDTO > boats ); + } +} \ No newline at end of file diff --git a/slips/src/app/Marina/Presentation/Views/IUpdateRegistrationView.cs b/slips/src/app/Marina/Presentation/Views/IUpdateRegistrationView.cs new file mode 100644 index 0000000..8474113 --- /dev/null +++ b/slips/src/app/Marina/Presentation/Views/IUpdateRegistrationView.cs @@ -0,0 +1,9 @@ +using System.Collections.Generic; +using Marina.Presentation.DTO; + +namespace Marina.Presentation.Views { + public interface IUpdateRegistrationView { + void Display( CustomerRegistrationDisplayDTO customerRegistration ); + void Display( IEnumerable< DisplayResponseLineDTO > response ); + } +} \ No newline at end of file diff --git a/slips/src/app/Marina/Properties/AssemblyInfo.cs b/slips/src/app/Marina/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..f9b9f7f --- /dev/null +++ b/slips/src/app/Marina/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("Marina")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("Marina")] +[assembly: AssemblyCopyright("Copyright © 2007")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("997b23e8-9d54-4169-a5a3-ace0266a1964")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/slips/src/app/Marina/Task/ApplicationStartupTask.cs b/slips/src/app/Marina/Task/ApplicationStartupTask.cs new file mode 100644 index 0000000..e55eccf --- /dev/null +++ b/slips/src/app/Marina/Task/ApplicationStartupTask.cs @@ -0,0 +1,14 @@ +using Marina.Infrastructure.Container; +using Marina.Infrastructure.Container.Windsor; + +namespace Marina.Task { + public class ApplicationStartupTask : IApplicationStartupTask { + public static void ApplicationBegin( ) { + new ApplicationStartupTask( ).Execute( ); + } + + public void Execute( ) { + Resolve.InitializeWith( new WindsorDependencyContainer( ) ); + } + } +} \ No newline at end of file diff --git a/slips/src/app/Marina/Task/AuthenticationTask.cs b/slips/src/app/Marina/Task/AuthenticationTask.cs new file mode 100644 index 0000000..75424a9 --- /dev/null +++ b/slips/src/app/Marina/Task/AuthenticationTask.cs @@ -0,0 +1,41 @@ +using Marina.Domain.Interfaces; +using Marina.Domain.Repositories; +using Marina.Presentation.DTO; +using Marina.Web.Http; + +namespace Marina.Task { + public class AuthenticationTask : IAuthenticationTask { + public AuthenticationTask( ICustomerRepository customers, IHttpGateway gateway ) { + _customers = customers; + _gateway = gateway; + } + + public DisplayResponseLineDTO AuthenticateUserUsing( LoginCredentialsDTO credentials ) { + if ( CheckIfPasswordMatches( credentials, _customers.FindBy( credentials.Username ) ) ) { + _gateway.AddAuthenticationCookieFor( credentials.Username, _customers.FindBy( credentials.Username ).ID( ) ); + return ValidCredentialsMessage( credentials.Username ); + } + else { + return InvalidCredentialsMessage( ); + } + } + + private static DisplayResponseLineDTO ValidCredentialsMessage( string username ) { + return new DisplayResponseLineDTO( string.Format( "Currently logged in as {0}", username ) ); + } + + private static DisplayResponseLineDTO InvalidCredentialsMessage() { + return new DisplayResponseLineDTO( "Invalid credentials specified" ); + } + + private static bool CheckIfPasswordMatches( LoginCredentialsDTO credentials, ICustomer customer ) { + if ( customer != null && customer.Registration( ) != null ) { + return customer.Registration( ).Password( ).Equals( credentials.Password ); + } + return false; + } + + private readonly ICustomerRepository _customers; + private readonly IHttpGateway _gateway; + } +} \ No newline at end of file diff --git a/slips/src/app/Marina/Task/CatalogTasks.cs b/slips/src/app/Marina/Task/CatalogTasks.cs new file mode 100644 index 0000000..e3c18a2 --- /dev/null +++ b/slips/src/app/Marina/Task/CatalogTasks.cs @@ -0,0 +1,52 @@ +using System.Collections.Generic; +using Marina.Domain.Interfaces; +using Marina.Domain.Repositories; +using Marina.Infrastructure.Container; +using Marina.Presentation.DTO; +using Marina.Task.Mappers; + +namespace Marina.Task { + public class CatalogTasks : ICatalogTasks { + public CatalogTasks() + : this( + Resolve.DependencyFor< ISlipsRepository >( ), + Resolve.DependencyFor< ISlipsToDisplayDTOMapper >( ), + Resolve.DependencyFor< IDockRepository >( ), + Resolve.DependencyFor< IDockToDisplayDTOMapper >( ) + ) {} + + public CatalogTasks( ISlipsRepository slipRepository, ISlipsToDisplayDTOMapper slipMapper, + IDockRepository dockRepository, IDockToDisplayDTOMapper dockMapper ) { + _slips = slipRepository; + _slipMapper = slipMapper; + _docks = dockRepository; + _dockMapper = dockMapper; + } + + public IEnumerable< SlipDisplayDTO > GetAvailableSlipsForDockBy( long dockId ) { + IDock dock = _docks.FindBy( dockId ); + foreach ( ISlip slip in _slips.AllAvailableSlipsFor( dock ) ) { + yield return _slipMapper.MapFrom( slip ); + } + } + + public DockDisplayDTO GetDockInformationBy( long dockId ) { + return _dockMapper.MapFrom( _docks.FindBy( dockId ) ); + } + + public IEnumerable< SlipDisplayDTO > GetAllAvailableSlips() { + foreach ( ISlip availableSlip in _slips.AllAvailableSlips( ) ) { + yield return _slipMapper.MapFrom( availableSlip ); + } + } + + public SlipDisplayDTO FindSlipBy( long slipId ) { + return _slipMapper.MapFrom( _slips.FindBy( slipId ) ); + } + + private readonly ISlipsRepository _slips; + private readonly ISlipsToDisplayDTOMapper _slipMapper; + private readonly IDockRepository _docks; + private readonly IDockToDisplayDTOMapper _dockMapper; + } +} \ No newline at end of file diff --git a/slips/src/app/Marina/Task/IApplicationStartupTask.cs b/slips/src/app/Marina/Task/IApplicationStartupTask.cs new file mode 100644 index 0000000..8fcdf6e --- /dev/null +++ b/slips/src/app/Marina/Task/IApplicationStartupTask.cs @@ -0,0 +1,5 @@ +namespace Marina.Task { + public interface IApplicationStartupTask { + void Execute( ); + } +} \ No newline at end of file diff --git a/slips/src/app/Marina/Task/IAuthenticationTask.cs b/slips/src/app/Marina/Task/IAuthenticationTask.cs new file mode 100644 index 0000000..9072578 --- /dev/null +++ b/slips/src/app/Marina/Task/IAuthenticationTask.cs @@ -0,0 +1,7 @@ +using Marina.Presentation.DTO; + +namespace Marina.Task { + public interface IAuthenticationTask { + DisplayResponseLineDTO AuthenticateUserUsing( LoginCredentialsDTO credentials ); + } +} \ No newline at end of file diff --git a/slips/src/app/Marina/Task/ICatalogTasks.cs b/slips/src/app/Marina/Task/ICatalogTasks.cs new file mode 100644 index 0000000..5d438a2 --- /dev/null +++ b/slips/src/app/Marina/Task/ICatalogTasks.cs @@ -0,0 +1,14 @@ +using System.Collections.Generic; +using Marina.Presentation.DTO; + +namespace Marina.Task { + public interface ICatalogTasks { + IEnumerable< SlipDisplayDTO > GetAvailableSlipsForDockBy( long dockId ); + + DockDisplayDTO GetDockInformationBy( long dockId ); + + IEnumerable< SlipDisplayDTO > GetAllAvailableSlips(); + + SlipDisplayDTO FindSlipBy( long slipId ); + } +} \ No newline at end of file diff --git a/slips/src/app/Marina/Task/ILeaseTasks.cs b/slips/src/app/Marina/Task/ILeaseTasks.cs new file mode 100644 index 0000000..f781a29 --- /dev/null +++ b/slips/src/app/Marina/Task/ILeaseTasks.cs @@ -0,0 +1,10 @@ +using System.Collections.Generic; +using Marina.Presentation.DTO; + +namespace Marina.Task { + public interface ILeaseTasks { + IEnumerable< DisplayLeaseDTO > FindAllLeasesFor( long customerId ); + + DisplayResponseLineDTO RequestLeaseUsing( SubmitLeaseRequestDTO request ); + } +} \ No newline at end of file diff --git a/slips/src/app/Marina/Task/IRegistrationTasks.cs b/slips/src/app/Marina/Task/IRegistrationTasks.cs new file mode 100644 index 0000000..97974b3 --- /dev/null +++ b/slips/src/app/Marina/Task/IRegistrationTasks.cs @@ -0,0 +1,16 @@ +using System.Collections.Generic; +using Marina.Presentation.DTO; + +namespace Marina.Task { + public interface IRegistrationTasks { + IEnumerable< DisplayResponseLineDTO > RegisterNew( RegisterCustomerDTO customer ); + + IEnumerable< DisplayResponseLineDTO > AddNewBoatUsing( BoatRegistrationDTO boat ); + + CustomerRegistrationDisplayDTO LoadRegistrationFor( long customerId ); + + IEnumerable< DisplayResponseLineDTO > UpdateRegistrationFor( UpdateCustomerRegistrationDTO registration ); + + IEnumerable< BoatRegistrationDTO > AllBoatsFor( long customerId ); + } +} \ No newline at end of file diff --git a/slips/src/app/Marina/Task/LeaseTasks.cs b/slips/src/app/Marina/Task/LeaseTasks.cs new file mode 100644 index 0000000..1dfb592 --- /dev/null +++ b/slips/src/app/Marina/Task/LeaseTasks.cs @@ -0,0 +1,39 @@ +using System.Collections.Generic; +using Marina.Domain; +using Marina.Domain.Exceptions; +using Marina.Domain.Interfaces; +using Marina.Domain.Repositories; +using Marina.Infrastructure; +using Marina.Presentation.DTO; +using Marina.Task.Mappers; + +namespace Marina.Task { + public class LeaseTasks : ILeaseTasks { + public LeaseTasks( ICustomerRepository customers, ISlipsRepository slips, ILeaseToDtoMapper mapper ) { + _customers = customers; + _slips = slips; + _mapper = mapper; + } + + public IEnumerable< DisplayLeaseDTO > FindAllLeasesFor( long customerId ) { + return new EnumerableMapper< ISlipLease, DisplayLeaseDTO >( _mapper ) + .MapFrom( _customers.FindBy( customerId ).Leases( ) ); + } + + public DisplayResponseLineDTO RequestLeaseUsing( SubmitLeaseRequestDTO request ) { + ICustomer customer = _customers.FindBy( request.CustomerId ); + try { + customer.Lease( _slips.FindBy( request.SlipId ), LeaseDurations.FindBy( request.Duration ) ); + _customers.Save( customer ); + return new DisplayResponseLineDTO( "Success!" ); + } + catch ( SlipIsAlreadyLeasedException ) { + return new DisplayResponseLineDTO( "Slip is already leased!" ); + } + } + + private readonly ICustomerRepository _customers; + private readonly ISlipsRepository _slips; + private readonly ILeaseToDtoMapper _mapper; + } +} \ No newline at end of file diff --git a/slips/src/app/Marina/Task/Mappers/BrokenRulesToDisplayItemMapper.cs b/slips/src/app/Marina/Task/Mappers/BrokenRulesToDisplayItemMapper.cs new file mode 100644 index 0000000..5a9aee6 --- /dev/null +++ b/slips/src/app/Marina/Task/Mappers/BrokenRulesToDisplayItemMapper.cs @@ -0,0 +1,13 @@ +using System.Collections.Generic; +using Marina.Domain.Interfaces; +using Marina.Presentation.DTO; + +namespace Marina.Task.Mappers { + public class BrokenRulesToDisplayItemMapper : IBrokenRulesToDisplayItemMapper { + public IEnumerable< DisplayResponseLineDTO > MapFrom( IEnumerable< IBrokenRule > input ) { + foreach ( IBrokenRule brokenRule in input ) { + yield return new DisplayResponseLineDTO( brokenRule.Message( ) ); + } + } + } +} \ No newline at end of file diff --git a/slips/src/app/Marina/Task/Mappers/DockToDisplayDTOMapper.cs b/slips/src/app/Marina/Task/Mappers/DockToDisplayDTOMapper.cs new file mode 100644 index 0000000..89ef037 --- /dev/null +++ b/slips/src/app/Marina/Task/Mappers/DockToDisplayDTOMapper.cs @@ -0,0 +1,16 @@ +using Marina.Domain; +using Marina.Domain.Interfaces; +using Marina.Presentation.DTO; + +namespace Marina.Task.Mappers { + public class DockToDisplayDTOMapper : IDockToDisplayDTOMapper { + public DockDisplayDTO MapFrom( IDock input ) { + return + new DockDisplayDTO( + input.Name( ), + input.Location( ).Name( ), + input.IsUtilityEnabled( Utilities.Water ).ToString( ), + input.IsUtilityEnabled( Utilities.Electrical ).ToString( ) ); + } + } +} \ No newline at end of file diff --git a/slips/src/app/Marina/Task/Mappers/IBrokenRulesToDisplayItemMapper.cs b/slips/src/app/Marina/Task/Mappers/IBrokenRulesToDisplayItemMapper.cs new file mode 100644 index 0000000..1af9300 --- /dev/null +++ b/slips/src/app/Marina/Task/Mappers/IBrokenRulesToDisplayItemMapper.cs @@ -0,0 +1,9 @@ +using System.Collections.Generic; +using Marina.Domain.Interfaces; +using Marina.Infrastructure; +using Marina.Presentation.DTO; + +namespace Marina.Task.Mappers { + public interface IBrokenRulesToDisplayItemMapper : + IMapper< IEnumerable< IBrokenRule >, IEnumerable< DisplayResponseLineDTO > > {} +} \ No newline at end of file diff --git a/slips/src/app/Marina/Task/Mappers/IDockToDisplayDTOMapper.cs b/slips/src/app/Marina/Task/Mappers/IDockToDisplayDTOMapper.cs new file mode 100644 index 0000000..264a92a --- /dev/null +++ b/slips/src/app/Marina/Task/Mappers/IDockToDisplayDTOMapper.cs @@ -0,0 +1,7 @@ +using Marina.Domain.Interfaces; +using Marina.Infrastructure; +using Marina.Presentation.DTO; + +namespace Marina.Task.Mappers { + public interface IDockToDisplayDTOMapper : IMapper< IDock, DockDisplayDTO > {} +} \ No newline at end of file diff --git a/slips/src/app/Marina/Task/Mappers/ILeaseToDtoMapper.cs b/slips/src/app/Marina/Task/Mappers/ILeaseToDtoMapper.cs new file mode 100644 index 0000000..473ed68 --- /dev/null +++ b/slips/src/app/Marina/Task/Mappers/ILeaseToDtoMapper.cs @@ -0,0 +1,7 @@ +using Marina.Domain.Interfaces; +using Marina.Infrastructure; +using Marina.Presentation.DTO; + +namespace Marina.Task.Mappers { + public interface ILeaseToDtoMapper : IMapper< ISlipLease, DisplayLeaseDTO > {} +} \ No newline at end of file diff --git a/slips/src/app/Marina/Task/Mappers/ISlipsToDisplayDTOMapper.cs b/slips/src/app/Marina/Task/Mappers/ISlipsToDisplayDTOMapper.cs new file mode 100644 index 0000000..95f97ba --- /dev/null +++ b/slips/src/app/Marina/Task/Mappers/ISlipsToDisplayDTOMapper.cs @@ -0,0 +1,7 @@ +using Marina.Domain.Interfaces; +using Marina.Infrastructure; +using Marina.Presentation.DTO; + +namespace Marina.Task.Mappers { + public interface ISlipsToDisplayDTOMapper : IMapper< ISlip, SlipDisplayDTO > {} +} \ No newline at end of file diff --git a/slips/src/app/Marina/Task/Mappers/LeaseToDtoMapper.cs b/slips/src/app/Marina/Task/Mappers/LeaseToDtoMapper.cs new file mode 100644 index 0000000..a776f52 --- /dev/null +++ b/slips/src/app/Marina/Task/Mappers/LeaseToDtoMapper.cs @@ -0,0 +1,12 @@ +using Marina.Domain.Interfaces; +using Marina.Presentation.DTO; + +namespace Marina.Task.Mappers { + public class LeaseToDtoMapper : ILeaseToDtoMapper { + public DisplayLeaseDTO MapFrom( ISlipLease input ) { + return new DisplayLeaseDTO( input.Slip( ).ID( ).ToString( ), + input.StartDate( ).ToString( ), + input.ExpiryDate( ).ToString( ) ); + } + } +} \ No newline at end of file diff --git a/slips/src/app/Marina/Task/Mappers/SlipsToDisplayDTOMapper.cs b/slips/src/app/Marina/Task/Mappers/SlipsToDisplayDTOMapper.cs new file mode 100644 index 0000000..c5ba592 --- /dev/null +++ b/slips/src/app/Marina/Task/Mappers/SlipsToDisplayDTOMapper.cs @@ -0,0 +1,16 @@ +using Marina.Domain.Interfaces; +using Marina.Presentation.DTO; + +namespace Marina.Task.Mappers { + public class SlipsToDisplayDTOMapper : ISlipsToDisplayDTOMapper { + public SlipDisplayDTO MapFrom( ISlip input ) { + return + new SlipDisplayDTO( input.Dock( ).ID( ).ToString( ), + input.Dock( ).Name( ), + input.Width( ).ToString( ), + input.Length( ).ToString( ), + input.Location( ).Name( ), + input.ID( ).ToString( ) ); + } + } +} \ No newline at end of file diff --git a/slips/src/app/Marina/Task/RegistrationTasks.cs b/slips/src/app/Marina/Task/RegistrationTasks.cs new file mode 100644 index 0000000..44c60ee --- /dev/null +++ b/slips/src/app/Marina/Task/RegistrationTasks.cs @@ -0,0 +1,92 @@ +using System; +using System.Collections.Generic; +using Marina.Domain.Interfaces; +using Marina.Domain.Repositories; +using Marina.Infrastructure.Container; +using Marina.Presentation.DTO; +using Marina.Task.Mappers; + +namespace Marina.Task { + public class RegistrationTasks : IRegistrationTasks { + public RegistrationTasks() + : this( + Resolve.DependencyFor< IBrokenRulesToDisplayItemMapper >( ), + Resolve.DependencyFor< ICustomerRepository >( ) + ) {} + + public RegistrationTasks( IBrokenRulesToDisplayItemMapper mapper, ICustomerRepository customers ) { + _mapper = mapper; + _customers = customers; + } + + public IEnumerable< DisplayResponseLineDTO > RegisterNew( RegisterCustomerDTO customer ) { + if ( null == _customers.FindBy( customer.UserName ) ) { + ICustomer newCustomer = _customers.NewCustomer( ); + newCustomer.RegisterAccount( customer.UserName, + customer.Password, + customer.FirstName, + customer.LastName, + customer.Phone, + customer.City ); + if ( !newCustomer.Registration( ).IsValid( ) ) { + return _mapper.MapFrom( newCustomer.Registration( ).BrokenRules( ) ); + } + else { + _customers.Save( newCustomer ); + return new DisplayResponseLines( "Success!" ); + } + } + else { + return + new DisplayResponseLines( + string.Format( "The username {0} is already taken. Please try another!", customer.UserName ) ); + } + } + + public IEnumerable< DisplayResponseLineDTO > AddNewBoatUsing( BoatRegistrationDTO boat ) { + ICustomer customer = _customers.FindBy( boat.CustomerId ); + customer.RegisterBoat( boat.RegistrationNumber, + boat.Manufacturer, + new DateTime( Convert.ToInt32( boat.ModelYear ), 1, 1 ), + Convert.ToInt64( boat.Length ) ); + _customers.Save( customer ); + return new DisplayResponseLines( "Success!" ); + } + + public CustomerRegistrationDisplayDTO LoadRegistrationFor( long customerId ) { + IRegistration registration = _customers.FindBy( customerId ).Registration( ); + return + new CustomerRegistrationDisplayDTO( customerId.ToString( ), + registration.Username( ), + registration.FirstName( ), + registration.LastName( ), + registration.PhoneNumber( ), + registration.City( ) + ); + } + + public IEnumerable< DisplayResponseLineDTO > UpdateRegistrationFor( UpdateCustomerRegistrationDTO registration ) { + ICustomer customer = _customers.FindBy( registration.CustomerId ); + + customer.UpdateRegistrationTo( registration.Username, registration.Password, registration.FirstName, + registration.LastName, registration.PhoneNumber, registration.City ); + if ( customer.Registration( ).IsValid( ) ) { + _customers.Save( customer ); + } + return _mapper.MapFrom( customer.Registration( ).BrokenRules( ) ); + } + + public IEnumerable< BoatRegistrationDTO > AllBoatsFor( long customerId ) { + ICustomer customer = _customers.FindBy( customerId ); + + foreach ( IBoat boat in customer.RegisteredBoats( ) ) { + yield return + new BoatRegistrationDTO( boat.RegistrationNumber( ), boat.Manufacturer( ), boat.YearOfModel( ).ToString( ), + boat.LengthInFeet( ).ToString( ), customerId ); + } + } + + private readonly IBrokenRulesToDisplayItemMapper _mapper; + private readonly ICustomerRepository _customers; + } +} \ No newline at end of file diff --git a/slips/src/app/Marina/Web/AuthenticationHttpModule.cs b/slips/src/app/Marina/Web/AuthenticationHttpModule.cs new file mode 100644 index 0000000..c90c317 --- /dev/null +++ b/slips/src/app/Marina/Web/AuthenticationHttpModule.cs @@ -0,0 +1,28 @@ +using System.Security.Principal; +using System.Web; +using System.Web.Security; + +namespace Marina.Web { + public class AuthenticationHttpModule : IHttpModule { + public void Init( HttpApplication context ) { + context.AuthenticateRequest += delegate { AuthenticateHttpRequest( ); }; + } + + public void Dispose() {} + + public void AuthenticateHttpRequest() { + HttpCookie cookie = GetCookieFrom( HttpContext.Current ); + if ( null != cookie ) { + BindPrincipalToThreadUsing( FormsAuthentication.Decrypt( cookie.Value ).Name ); + } + } + + private HttpCookie GetCookieFrom( HttpContext context ) { + return context.Request.Cookies[ FormsAuthentication.FormsCookieName ]; + } + + private void BindPrincipalToThreadUsing( string username ) { + HttpContext.Current.User = new GenericPrincipal( new GenericIdentity( username ), new string[] {"Customer"} ); + } + } +} \ No newline at end of file diff --git a/slips/src/app/Marina/Web/Commands/AvailableSlipsCommand.cs b/slips/src/app/Marina/Web/Commands/AvailableSlipsCommand.cs new file mode 100644 index 0000000..4c14b14 --- /dev/null +++ b/slips/src/app/Marina/Web/Commands/AvailableSlipsCommand.cs @@ -0,0 +1,23 @@ +using Marina.Infrastructure; +using Marina.Infrastructure.Container; +using Marina.Task; +using Marina.Web.Views.Pages; + +namespace Marina.Web.Commands { + public class AvailableSlipsCommand : ICommand { + public AvailableSlipsCommand() : this( new AvailableSlipsWebView( ), Resolve.DependencyFor< ICatalogTasks >( ) ) {} + + public AvailableSlipsCommand( IAvailableSlipsWebView view, ICatalogTasks task ) { + _view = view; + _task = task; + } + + public void Execute() { + _view.AddToBag( _task.GetAllAvailableSlips( ) ); + _view.Render( ); + } + + private readonly IAvailableSlipsWebView _view; + private readonly ICatalogTasks _task; + } +} \ No newline at end of file diff --git a/slips/src/app/Marina/Web/Commands/CommandNames.cs b/slips/src/app/Marina/Web/Commands/CommandNames.cs new file mode 100644 index 0000000..a676be7 --- /dev/null +++ b/slips/src/app/Marina/Web/Commands/CommandNames.cs @@ -0,0 +1,5 @@ +namespace Marina.Web.Commands { + public class CommandNames { + public const string AvailableSlips = "AvailableSlips.marina"; + } +} \ No newline at end of file diff --git a/slips/src/app/Marina/Web/Commands/RedirectCommand.cs b/slips/src/app/Marina/Web/Commands/RedirectCommand.cs new file mode 100644 index 0000000..c87c423 --- /dev/null +++ b/slips/src/app/Marina/Web/Commands/RedirectCommand.cs @@ -0,0 +1,11 @@ +using Marina.Infrastructure; +using Marina.Web.Views; + +namespace Marina.Web.Commands { + public class RedirectCommand : ICommand { + public void Execute() { + Redirect.To( WebViews.Login ); + //throw new Exception( "Could not find a handler for request" ); + } + } +} \ No newline at end of file diff --git a/slips/src/app/Marina/Web/CurrentHttpContext.cs b/slips/src/app/Marina/Web/CurrentHttpContext.cs new file mode 100644 index 0000000..8f3b959 --- /dev/null +++ b/slips/src/app/Marina/Web/CurrentHttpContext.cs @@ -0,0 +1,135 @@ +using System; +using System.Collections; +using System.Security.Principal; +using System.Web; +using System.Web.Caching; +using System.Web.Profile; +using System.Web.SessionState; + +namespace Marina.Web { + public class CurrentHttpContext : IHttpContext { + public void AddError( Exception errorInfo ) { + Current( ).AddError( errorInfo ); + } + + public void ClearError() { + Current( ).ClearError( ); + } + + public object GetSection( string sectionName ) { + return Current( ).GetSection( sectionName ); + } + + public void RewritePath( string path ) { + Current( ).RewritePath( path ); + } + + public void RewritePath( string path, bool rebaseClientPath ) { + Current( ).RewritePath( path, rebaseClientPath ); + } + + public void RewritePath( string filePath, string pathInfo, string queryString ) { + Current( ).RewritePath( filePath, pathInfo, queryString ); + } + + public void RewritePath( string filePath, string pathInfo, string queryString, bool setClientFilePath ) { + Current( ).RewritePath( filePath, pathInfo, queryString, setClientFilePath ); + } + + public HttpApplication ApplicationInstance { + get { return Current( ).ApplicationInstance; } + set { Current( ).ApplicationInstance = value; } + } + + public HttpApplicationState Application { + get { return Current( ).Application; } + } + + public IHttpHandler Handler { + get { return Current( ).Handler; } + set { Current( ).Handler = value; } + } + + public IHttpHandler PreviousHandler { + get { return Current( ).PreviousHandler; } + } + + public IHttpHandler CurrentHandler { + get { return Current( ).CurrentHandler; } + } + + public HttpRequest Request { + get { return Current( ).Request; } + } + + public HttpResponse Response { + get { return Current( ).Response; } + } + + public TraceContext Trace { + get { return Current( ).Trace; } + } + + public IDictionary Items { + get { return Current( ).Items; } + } + + public HttpSessionState Session { + get { return Current( ).Session; } + } + + public HttpServerUtility Server { + get { return Current( ).Server; } + } + + public Exception Error { + get { return Current( ).Error; } + } + + public Exception[] AllErrors { + get { return Current( ).AllErrors; } + } + + public IPrincipal User { + get { return Current( ).User; } + set { Current( ).User = value; } + } + + public ProfileBase Profile { + get { return Current( ).Profile; } + } + + public bool SkipAuthorization { + get { return Current( ).SkipAuthorization; } + set { Current( ).SkipAuthorization = value; } + } + + public bool IsDebuggingEnabled { + get { return Current( ).IsDebuggingEnabled; } + } + + public bool IsCustomErrorEnabled { + get { return Current( ).IsCustomErrorEnabled; } + } + + public DateTime Timestamp { + get { return Current( ).Timestamp; } + } + + public Cache Cache { + get { return Current( ).Cache; } + } + + public RequestNotification CurrentNotification { + get { return Current( ).CurrentNotification; } + } + + public bool IsPostNotification { + get { return Current( ).IsPostNotification; } + } + + private HttpContext Current() { + return HttpContext.Current; + } + } +} \ No newline at end of file diff --git a/slips/src/app/Marina/Web/CurrentHttpRequest.cs b/slips/src/app/Marina/Web/CurrentHttpRequest.cs new file mode 100644 index 0000000..35c4fa5 --- /dev/null +++ b/slips/src/app/Marina/Web/CurrentHttpRequest.cs @@ -0,0 +1,20 @@ +using System.Collections.Specialized; +using Marina.Presentation; + +namespace Marina.Web { + public class CurrentHttpRequest : IHttpRequest { + public CurrentHttpRequest( IHttpContext context ) { + _context = context; + } + + public T ParsePayloadFor< T >( PayloadKey< T > key ) { + return key.ParseFrom( Payload( ) ); + } + + private NameValueCollection Payload() { + return new NameValueCollection( _context.Request.Params ); + } + + private readonly IHttpContext _context; + } +} \ No newline at end of file diff --git a/slips/src/app/Marina/Web/FrontController.cs b/slips/src/app/Marina/Web/FrontController.cs new file mode 100644 index 0000000..8090cb9 --- /dev/null +++ b/slips/src/app/Marina/Web/FrontController.cs @@ -0,0 +1,21 @@ +using System.Web; +using Marina.Web.Handlers; +using Marina.Web.Http; + +namespace Marina.Web { + public class FrontController : IHttpHandler { + public FrontController( IHttpGateway gateway ) { + _gateway = gateway; + } + + public void ProcessRequest( HttpContext context ) { + new Dispatcher( ).FindFor( _gateway ).Execute( ); + } + + public bool IsReusable { + get { return true; } + } + + private IHttpGateway _gateway; + } +} \ No newline at end of file diff --git a/slips/src/app/Marina/Web/GlobalApplication.cs b/slips/src/app/Marina/Web/GlobalApplication.cs new file mode 100644 index 0000000..452587f --- /dev/null +++ b/slips/src/app/Marina/Web/GlobalApplication.cs @@ -0,0 +1,17 @@ +using System; +using System.Web; +using Marina.Infrastructure.Logging.Interfaces; +using Marina.Task; + +namespace Marina.Web { + public class GlobalApplication : HttpApplication { + public void Application_Start( object sender, EventArgs e ) { + ApplicationStartupTask.ApplicationBegin( ); + Log.For(this).Informational("Application Startup completed"); + } + + public void Application_Error( object sender, EventArgs e ) { + Log.For( this ).Informational( "Unhandled error occurred" ); + } + } +} \ No newline at end of file diff --git a/slips/src/app/Marina/Web/Handlers/AvailableSlipsHandler.cs b/slips/src/app/Marina/Web/Handlers/AvailableSlipsHandler.cs new file mode 100644 index 0000000..a8c69d5 --- /dev/null +++ b/slips/src/app/Marina/Web/Handlers/AvailableSlipsHandler.cs @@ -0,0 +1,7 @@ +using Marina.Web.Commands; + +namespace Marina.Web.Handlers { + public class AvailableSlipsHandler : RequestHandler { + public AvailableSlipsHandler() : base( For( CommandNames.AvailableSlips ), new AvailableSlipsCommand( ) ) {} + } +} \ No newline at end of file diff --git a/slips/src/app/Marina/Web/Handlers/Dispatcher.cs b/slips/src/app/Marina/Web/Handlers/Dispatcher.cs new file mode 100644 index 0000000..af1bd84 --- /dev/null +++ b/slips/src/app/Marina/Web/Handlers/Dispatcher.cs @@ -0,0 +1,24 @@ +using Marina.Infrastructure; +using Marina.Web.Commands; +using Marina.Web.Http; + +namespace Marina.Web.Handlers { + public class Dispatcher { + private readonly IRegisteredHandlers handlers; + + public Dispatcher() : this( new RegisteredHandlers( ) ) {} + + public Dispatcher( IRegisteredHandlers handlers ) { + this.handlers = handlers; + } + + public ICommand FindFor( IHttpGateway request ) { + foreach ( IRequestHandler handler in handlers.All( ) ) { + if ( handler.IsSatisfiedBy( request ) ) { + return handler; + } + } + return new RedirectCommand( ); + } + } +} \ No newline at end of file diff --git a/slips/src/app/Marina/Web/Handlers/IRegisteredHandlers.cs b/slips/src/app/Marina/Web/Handlers/IRegisteredHandlers.cs new file mode 100644 index 0000000..3049638 --- /dev/null +++ b/slips/src/app/Marina/Web/Handlers/IRegisteredHandlers.cs @@ -0,0 +1,8 @@ +using System.Collections.Generic; +using Marina.Web.Handlers; + +namespace Marina.Web.Handlers { + public interface IRegisteredHandlers { + IEnumerable< IRequestHandler > All( ); + } +} \ No newline at end of file diff --git a/slips/src/app/Marina/Web/Handlers/IRequestHandler.cs b/slips/src/app/Marina/Web/Handlers/IRequestHandler.cs new file mode 100644 index 0000000..e33552e --- /dev/null +++ b/slips/src/app/Marina/Web/Handlers/IRequestHandler.cs @@ -0,0 +1,6 @@ +using Marina.Infrastructure; +using Marina.Web.Http; + +namespace Marina.Web.Handlers { + public interface IRequestHandler : ISpecification< IHttpGateway >, ICommand {} +} \ No newline at end of file diff --git a/slips/src/app/Marina/Web/Handlers/RegisteredHandlers.cs b/slips/src/app/Marina/Web/Handlers/RegisteredHandlers.cs new file mode 100644 index 0000000..1f6395f --- /dev/null +++ b/slips/src/app/Marina/Web/Handlers/RegisteredHandlers.cs @@ -0,0 +1,9 @@ +using System.Collections.Generic; + +namespace Marina.Web.Handlers { + public class RegisteredHandlers : IRegisteredHandlers { + public IEnumerable< IRequestHandler > All() { + yield return new AvailableSlipsHandler( ); + } + } +} \ No newline at end of file diff --git a/slips/src/app/Marina/Web/Handlers/RequestHandler.cs b/slips/src/app/Marina/Web/Handlers/RequestHandler.cs new file mode 100644 index 0000000..a2162ef --- /dev/null +++ b/slips/src/app/Marina/Web/Handlers/RequestHandler.cs @@ -0,0 +1,26 @@ +using Marina.Infrastructure; +using Marina.Web.Http; + +namespace Marina.Web.Handlers { + public class RequestHandler : IRequestHandler { + public RequestHandler( ISpecification< IHttpGateway > specification, ICommand command ) { + _specification = specification; + _command = command; + } + + public bool IsSatisfiedBy( IHttpGateway item ) { + return _specification.IsSatisfiedBy( item ); + } + + public void Execute() { + _command.Execute( ); + } + + public static ISpecification< IHttpGateway > For( string commandName ) { + return new RequestHandlerSpecification( commandName ); + } + + private readonly ISpecification< IHttpGateway > _specification; + private readonly ICommand _command; + } +} \ No newline at end of file diff --git a/slips/src/app/Marina/Web/Handlers/RequestHandlerSpecification.cs b/slips/src/app/Marina/Web/Handlers/RequestHandlerSpecification.cs new file mode 100644 index 0000000..51dd893 --- /dev/null +++ b/slips/src/app/Marina/Web/Handlers/RequestHandlerSpecification.cs @@ -0,0 +1,16 @@ +using Marina.Infrastructure; +using Marina.Web.Http; + +namespace Marina.Web.Handlers { + public class RequestHandlerSpecification : ISpecification< IHttpGateway > { + private readonly string _commandName; + + public RequestHandlerSpecification( string commandName ) { + _commandName = commandName; + } + + public bool IsSatisfiedBy( IHttpGateway item ) { + return item.Destination( ).Contains( _commandName ); + } + } +} \ No newline at end of file diff --git a/slips/src/app/Marina/Web/Http/HttpGateway.cs b/slips/src/app/Marina/Web/Http/HttpGateway.cs new file mode 100644 index 0000000..4b91315 --- /dev/null +++ b/slips/src/app/Marina/Web/Http/HttpGateway.cs @@ -0,0 +1,71 @@ +using System; +using System.Collections.Specialized; +using System.Security.Principal; +using System.Web; +using System.Web.Security; +using Marina.Infrastructure.Logging.Interfaces; +using Marina.Presentation; +using Marina.Web.Views; + +namespace Marina.Web.Http { + public class HttpGateway : IHttpGateway { + public HttpGateway( IHttpContext context ) { + _context = context; + } + + public string Destination() { + return _context.Request.RawUrl; + } + + public void RedirectTo( IView view ) { + try { + _context.Server.Transfer( view.Name( ) ); + } + catch ( Exception ex ) { + Log.For( this ).CriticalError( ex.StackTrace ); + } + } + + public void AddAuthenticationCookieFor( string username, long customerId ) { + AddCookieToResponse( username, customerId ); + BindPrincipalToCurrentThread( username ); + } + + public T ParsePayloadFor< T >( PayloadKey< T > key ) { + return key.ParseFrom( Payload( ) ); + } + + public bool ContainsPayload< T >( PayloadKey< T > key ) { + try { + ParsePayloadFor( key ); + return true; + } + catch ( PayloadKeyNotFoundException ) { + return false; + } + } + + private NameValueCollection Payload() { + return new NameValueCollection( _context.Request.Params ); + } + + private void BindPrincipalToCurrentThread( string username ) { + _context.User = new GenericPrincipal( new GenericIdentity( username ), new string[] {"Customer"} ); + } + + private void AddCookieToResponse( string username, long customerId ) { + FormsAuthenticationTicket ticket = + new FormsAuthenticationTicket( 1, username, DateTime.Now, DateTime.Now.AddMinutes( 20 ), false, + customerId.ToString( ) ); + + _context.Response.Cookies.Add( CreateCookieFrom( ticket ) ); + _context.Response.Cookies.Add( new HttpCookie( PayloadKeys.CustomerId, customerId.ToString( ) ) ); + } + + private HttpCookie CreateCookieFrom( FormsAuthenticationTicket ticket ) { + return new HttpCookie( FormsAuthentication.FormsCookieName, FormsAuthentication.Encrypt( ticket ) ); + } + + private IHttpContext _context; + } +} \ No newline at end of file diff --git a/slips/src/app/Marina/Web/Http/IHttpGateway.cs b/slips/src/app/Marina/Web/Http/IHttpGateway.cs new file mode 100644 index 0000000..93164ad --- /dev/null +++ b/slips/src/app/Marina/Web/Http/IHttpGateway.cs @@ -0,0 +1,16 @@ +using Marina.Presentation; +using Marina.Web.Views; + +namespace Marina.Web.Http { + public interface IHttpGateway { + string Destination(); + + void RedirectTo( IView view ); + + void AddAuthenticationCookieFor( string username, long customerId ); + + bool ContainsPayload< T >( PayloadKey< T > key ); + + T ParsePayloadFor< T >( PayloadKey< T > key ); + } +} \ No newline at end of file diff --git a/slips/src/app/Marina/Web/IHttpContext.cs b/slips/src/app/Marina/Web/IHttpContext.cs new file mode 100644 index 0000000..186b8c4 --- /dev/null +++ b/slips/src/app/Marina/Web/IHttpContext.cs @@ -0,0 +1,69 @@ +using System; +using System.Collections; +using System.Security.Principal; +using System.Web; +using System.Web.Caching; +using System.Web.Profile; +using System.Web.SessionState; + +namespace Marina.Web { + public interface IHttpContext { + void AddError( Exception errorInfo ); + + void ClearError( ); + + object GetSection( string sectionName ); + + void RewritePath( string path ); + + void RewritePath( string path, bool rebaseClientPath ); + + void RewritePath( string filePath, string pathInfo, string queryString ); + + void RewritePath( string filePath, string pathInfo, string queryString, bool setClientFilePath ); + + HttpApplication ApplicationInstance { get; set; } + + HttpApplicationState Application { get; } + + IHttpHandler Handler { get; set; } + + IHttpHandler PreviousHandler { get; } + + IHttpHandler CurrentHandler { get; } + + HttpRequest Request { get; } + + HttpResponse Response { get; } + + TraceContext Trace { get; } + + IDictionary Items { get; } + + HttpSessionState Session { get; } + + HttpServerUtility Server { get; } + + Exception Error { get; } + + Exception[] AllErrors { get; } + + IPrincipal User { get; set; } + + ProfileBase Profile { get; } + + bool SkipAuthorization { get; set; } + + bool IsDebuggingEnabled { get; } + + bool IsCustomErrorEnabled { get; } + + DateTime Timestamp { get; } + + Cache Cache { get; } + + RequestNotification CurrentNotification { get; } + + bool IsPostNotification { get; } + } +} \ No newline at end of file diff --git a/slips/src/app/Marina/Web/IHttpRequest.cs b/slips/src/app/Marina/Web/IHttpRequest.cs new file mode 100644 index 0000000..be92c04 --- /dev/null +++ b/slips/src/app/Marina/Web/IHttpRequest.cs @@ -0,0 +1,7 @@ +using Marina.Presentation; + +namespace Marina.Web { + public interface IHttpRequest { + T ParsePayloadFor< T >( PayloadKey< T > key ); + } +} \ No newline at end of file diff --git a/slips/src/app/Marina/Web/Redirect.cs b/slips/src/app/Marina/Web/Redirect.cs new file mode 100644 index 0000000..de4a5fe --- /dev/null +++ b/slips/src/app/Marina/Web/Redirect.cs @@ -0,0 +1,10 @@ +using System.Web; +using Marina.Web.Views; + +namespace Marina.Web { + public class Redirect { + public static void To( IView page ) { + HttpContext.Current.Server.Transfer( page.Name( ) ); + } + } +} \ No newline at end of file diff --git a/slips/src/app/Marina/Web/Services/AuthenticationServices.asmx b/slips/src/app/Marina/Web/Services/AuthenticationServices.asmx new file mode 100644 index 0000000..773ace4 --- /dev/null +++ b/slips/src/app/Marina/Web/Services/AuthenticationServices.asmx @@ -0,0 +1 @@ +<%@ WebService Language="C#" CodeBehind="AuthenticationWebServices.cs" Class="Marina.Web.Services.AuthenticationWebServices" %> \ No newline at end of file diff --git a/slips/src/app/Marina/Web/Services/AuthenticationWebServices.cs b/slips/src/app/Marina/Web/Services/AuthenticationWebServices.cs new file mode 100644 index 0000000..f4002f6 --- /dev/null +++ b/slips/src/app/Marina/Web/Services/AuthenticationWebServices.cs @@ -0,0 +1,21 @@ +using System.Web.Services; +using Marina.Infrastructure.Container; +using Marina.Presentation.DTO; +using Marina.Task; + +namespace Marina.Web.Services { + public class AuthenticationWebServices : IAuthenticationTask { + public AuthenticationWebServices() : this( Resolve.DependencyFor< IAuthenticationTask >( ) ) {} + + public AuthenticationWebServices( IAuthenticationTask realTask ) { + this.realTask = realTask; + } + + [WebMethod] + public DisplayResponseLineDTO AuthenticateUserUsing( LoginCredentialsDTO credentials ) { + return realTask.AuthenticateUserUsing( credentials ); + } + + private readonly IAuthenticationTask realTask; + } +} \ No newline at end of file diff --git a/slips/src/app/Marina/Web/Services/CatalogServices.asmx b/slips/src/app/Marina/Web/Services/CatalogServices.asmx new file mode 100644 index 0000000..67943dc --- /dev/null +++ b/slips/src/app/Marina/Web/Services/CatalogServices.asmx @@ -0,0 +1 @@ +<%@ WebService Language="C#" CodeBehind="CatalogWebServices.cs" Class="Marina.Web.Services.CatalogWebServices" %> \ No newline at end of file diff --git a/slips/src/app/Marina/Web/Services/CatalogWebServices.cs b/slips/src/app/Marina/Web/Services/CatalogWebServices.cs new file mode 100644 index 0000000..6982cdd --- /dev/null +++ b/slips/src/app/Marina/Web/Services/CatalogWebServices.cs @@ -0,0 +1,35 @@ +using System.Collections.Generic; +using System.Web.Services; +using Marina.Infrastructure.Container; +using Marina.Presentation.DTO; +using Marina.Task; + +namespace Marina.Web.Services { + public class CatalogWebServices { + public CatalogWebServices() : this( Resolve.DependencyFor< ICatalogTasks >( ) ) {} + + public CatalogWebServices( ICatalogTasks underlyingTask ) { + _underlyingTask = underlyingTask; + } + + public IEnumerable< SlipDisplayDTO > GetAvailableSlipsForDockBy( long dockId ) { + return _underlyingTask.GetAvailableSlipsForDockBy( dockId ); + } + + [WebMethod] + public DockDisplayDTO GetDockInformationBy( long dockId ) { + return _underlyingTask.GetDockInformationBy( dockId ); + } + + public IEnumerable< SlipDisplayDTO > GetAllAvailableSlips() { + return _underlyingTask.GetAllAvailableSlips( ); + } + + [WebMethod] + public SlipDisplayDTO FindSlipBy( long slipId ) { + return _underlyingTask.FindSlipBy( slipId ); + } + + private readonly ICatalogTasks _underlyingTask; + } +} \ No newline at end of file diff --git a/slips/src/app/Marina/Web/Services/LeaseServices.asmx b/slips/src/app/Marina/Web/Services/LeaseServices.asmx new file mode 100644 index 0000000..648db51 --- /dev/null +++ b/slips/src/app/Marina/Web/Services/LeaseServices.asmx @@ -0,0 +1 @@ +<%@ WebService Language="C#" CodeBehind="LeaseWebServices.cs" Class="Marina.Web.Services.LeaseWebServices" %> \ No newline at end of file diff --git a/slips/src/app/Marina/Web/Services/LeaseWebServices.cs b/slips/src/app/Marina/Web/Services/LeaseWebServices.cs new file mode 100644 index 0000000..b09cc76 --- /dev/null +++ b/slips/src/app/Marina/Web/Services/LeaseWebServices.cs @@ -0,0 +1,26 @@ +using System.Collections.Generic; +using System.Web.Services; +using Marina.Infrastructure.Container; +using Marina.Presentation.DTO; +using Marina.Task; + +namespace Marina.Web.Services { + public class LeaseWebServices { + public LeaseWebServices() : this( Resolve.DependencyFor< ILeaseTasks >( ) ) {} + + public LeaseWebServices( ILeaseTasks underlyingTask ) { + _underlyingTask = underlyingTask; + } + + public IEnumerable< DisplayLeaseDTO > FindAllLeasesFor( long customerId ) { + return _underlyingTask.FindAllLeasesFor( customerId ); + } + + [WebMethod] + public DisplayResponseLineDTO RequestLeaseUsing( SubmitLeaseRequestDTO request ) { + return _underlyingTask.RequestLeaseUsing( request ); + } + + private readonly ILeaseTasks _underlyingTask; + } +} \ No newline at end of file diff --git a/slips/src/app/Marina/Web/Services/RegistrationServices.asmx b/slips/src/app/Marina/Web/Services/RegistrationServices.asmx new file mode 100644 index 0000000..364b737 --- /dev/null +++ b/slips/src/app/Marina/Web/Services/RegistrationServices.asmx @@ -0,0 +1 @@ +<%@ WebService Language="C#" CodeBehind="RegistrationWebServices.cs" Class="Marina.Web.Services.RegistrationWebServices" %> \ No newline at end of file diff --git a/slips/src/app/Marina/Web/Services/RegistrationWebServices.cs b/slips/src/app/Marina/Web/Services/RegistrationWebServices.cs new file mode 100644 index 0000000..ac98fe5 --- /dev/null +++ b/slips/src/app/Marina/Web/Services/RegistrationWebServices.cs @@ -0,0 +1,38 @@ +using System.Collections.Generic; +using System.Web.Services; +using Marina.Infrastructure.Container; +using Marina.Presentation.DTO; +using Marina.Task; + +namespace Marina.Web.Services { + public class RegistrationWebServices { + public RegistrationWebServices() : this( Resolve.DependencyFor< IRegistrationTasks >( ) ) {} + + public RegistrationWebServices( IRegistrationTasks underlyingTask ) { + _underlyingTask = underlyingTask; + } + + public IEnumerable< DisplayResponseLineDTO > RegisterNew( RegisterCustomerDTO customer ) { + return _underlyingTask.RegisterNew( customer ); + } + + public IEnumerable< DisplayResponseLineDTO > AddNewBoatUsing( BoatRegistrationDTO boat ) { + return _underlyingTask.AddNewBoatUsing( boat ); + } + + [WebMethod] + public CustomerRegistrationDisplayDTO LoadRegistrationFor( long customerId ) { + return _underlyingTask.LoadRegistrationFor( customerId ); + } + + public IEnumerable< DisplayResponseLineDTO > UpdateRegistrationFor( UpdateCustomerRegistrationDTO registration ) { + return _underlyingTask.UpdateRegistrationFor( registration ); + } + + public IEnumerable< BoatRegistrationDTO > AllBoatsFor( long customerId ) { + return _underlyingTask.AllBoatsFor( customerId ); + } + + private readonly IRegistrationTasks _underlyingTask; + } +} \ No newline at end of file diff --git a/slips/src/app/Marina/Web/UnhandledExceptionsHttpModule.cs b/slips/src/app/Marina/Web/UnhandledExceptionsHttpModule.cs new file mode 100644 index 0000000..d2267f2 --- /dev/null +++ b/slips/src/app/Marina/Web/UnhandledExceptionsHttpModule.cs @@ -0,0 +1,19 @@ +using System; +using System.Web; +using Marina.Infrastructure.Logging.Interfaces; +using Marina.Web.Views; + +namespace Marina.Web { + public class UnhandledExceptionsHttpModule : IHttpModule { + public void Init( HttpApplication context ) { + context.Error += delegate { + foreach ( Exception exception in context.Context.AllErrors ) { + Log.For( this ).CriticalError( exception.ToString( ) ); + } + Redirect.To( WebViews.Login ); + }; + } + + public void Dispose() {} + } +} \ No newline at end of file diff --git a/slips/src/app/Marina/Web/Views/IView.cs b/slips/src/app/Marina/Web/Views/IView.cs new file mode 100644 index 0000000..55c1595 --- /dev/null +++ b/slips/src/app/Marina/Web/Views/IView.cs @@ -0,0 +1,7 @@ +namespace Marina.Web.Views { + public interface IView { + string Name( ); + + void Render( ); + } +} \ No newline at end of file diff --git a/slips/src/app/Marina/Web/Views/IViewLuggageTicket.cs b/slips/src/app/Marina/Web/Views/IViewLuggageTicket.cs new file mode 100644 index 0000000..231a008 --- /dev/null +++ b/slips/src/app/Marina/Web/Views/IViewLuggageTicket.cs @@ -0,0 +1,3 @@ +namespace Marina.Web.Views { + public interface IViewLuggageTicket< T > {} +} \ No newline at end of file diff --git a/slips/src/app/Marina/Web/Views/IViewLuggageTransporter.cs b/slips/src/app/Marina/Web/Views/IViewLuggageTransporter.cs new file mode 100644 index 0000000..7256f86 --- /dev/null +++ b/slips/src/app/Marina/Web/Views/IViewLuggageTransporter.cs @@ -0,0 +1,7 @@ +namespace Marina.Web.Views { + public interface IViewLuggageTransporter< T > { + void Add( T value ); + + T Value( ); + } +} \ No newline at end of file diff --git a/slips/src/app/Marina/Web/Views/IWebView.cs b/slips/src/app/Marina/Web/Views/IWebView.cs new file mode 100644 index 0000000..52af842 --- /dev/null +++ b/slips/src/app/Marina/Web/Views/IWebView.cs @@ -0,0 +1,5 @@ +namespace Marina.Web.Views { + public interface IWebView< T > : IView { + void AddToBag( T slips ); + } +} \ No newline at end of file diff --git a/slips/src/app/Marina/Web/Views/Pages/AvailableSlipsWebView.cs b/slips/src/app/Marina/Web/Views/Pages/AvailableSlipsWebView.cs new file mode 100644 index 0000000..bf930a7 --- /dev/null +++ b/slips/src/app/Marina/Web/Views/Pages/AvailableSlipsWebView.cs @@ -0,0 +1,16 @@ +using System.Collections.Generic; +using Marina.Infrastructure.Container; +using Marina.Presentation.DTO; +using Marina.Web.Http; + +namespace Marina.Web.Views.Pages { + public class AvailableSlipsWebView : WebView< IEnumerable< SlipDisplayDTO > >, IAvailableSlipsWebView { + public AvailableSlipsWebView() + : this( + ViewLuggage.TransporterFor( ViewLuggageTickets.AvailableSlips ), + Resolve.DependencyFor< IHttpGateway >( ) ) {} + + public AvailableSlipsWebView( IViewLuggageTransporter< IEnumerable< SlipDisplayDTO > > viewBag, IHttpGateway gateway ) + : base( "AvailableSlips.aspx", viewBag, gateway ) {} + } +} \ No newline at end of file diff --git a/slips/src/app/Marina/Web/Views/Pages/IAvailableSlipsWebView.cs b/slips/src/app/Marina/Web/Views/Pages/IAvailableSlipsWebView.cs new file mode 100644 index 0000000..83535da --- /dev/null +++ b/slips/src/app/Marina/Web/Views/Pages/IAvailableSlipsWebView.cs @@ -0,0 +1,6 @@ +using System.Collections.Generic; +using Marina.Presentation.DTO; + +namespace Marina.Web.Views.Pages { + public interface IAvailableSlipsWebView : IWebView< IEnumerable< SlipDisplayDTO > > {} +} \ No newline at end of file diff --git a/slips/src/app/Marina/Web/Views/View.cs b/slips/src/app/Marina/Web/Views/View.cs new file mode 100644 index 0000000..9f22d8d --- /dev/null +++ b/slips/src/app/Marina/Web/Views/View.cs @@ -0,0 +1,28 @@ +using Marina.Infrastructure.Container; +using Marina.Web.Http; + +namespace Marina.Web.Views { + public class View : IView { + public View( string name ) : this( name, Resolve.DependencyFor< IHttpGateway >( ) ) {} + + public View( string name, IHttpGateway gateway ) { + _name = name; + _gateway = gateway; + } + + public string Name() { + return _name; + } + + public void Render() { + _gateway.RedirectTo( this ); + } + + public override string ToString() { + return Name( ); + } + + private readonly string _name; + private readonly IHttpGateway _gateway; + } +} \ No newline at end of file diff --git a/slips/src/app/Marina/Web/Views/ViewLuggage.cs b/slips/src/app/Marina/Web/Views/ViewLuggage.cs new file mode 100644 index 0000000..7e9580d --- /dev/null +++ b/slips/src/app/Marina/Web/Views/ViewLuggage.cs @@ -0,0 +1,11 @@ +namespace Marina.Web.Views { + public class ViewLuggage { + public static IViewLuggageTransporter< T > TransporterFor< T >( IViewLuggageTicket< T > ticket ) { + return new ViewLuggageTransporter< T >( ticket ); + } + + public static T ClaimFor< T >( IViewLuggageTicket< T > ticket ) { + return new ViewLuggageTransporter< T >( ticket ).Value( ); + } + } +} \ No newline at end of file diff --git a/slips/src/app/Marina/Web/Views/ViewLuggageTickets.cs b/slips/src/app/Marina/Web/Views/ViewLuggageTickets.cs new file mode 100644 index 0000000..3c30368 --- /dev/null +++ b/slips/src/app/Marina/Web/Views/ViewLuggageTickets.cs @@ -0,0 +1,14 @@ +using System.Collections.Generic; +using Marina.Presentation.DTO; + +namespace Marina.Web.Views { + public class ViewLuggageTickets { + public static IViewLuggageTicket< IEnumerable< SlipDisplayDTO > > AvailableSlips = + new ViewBagItem< IEnumerable< SlipDisplayDTO > >( ); + + public static IViewLuggageTicket< IEnumerable< DisplayResponseLineDTO > > ResponseMessages = + new ViewBagItem< IEnumerable< DisplayResponseLineDTO > >( ); + + private class ViewBagItem< T > : IViewLuggageTicket< T > {} + } +} \ No newline at end of file diff --git a/slips/src/app/Marina/Web/Views/ViewLuggageTransporter.cs b/slips/src/app/Marina/Web/Views/ViewLuggageTransporter.cs new file mode 100644 index 0000000..a86c734 --- /dev/null +++ b/slips/src/app/Marina/Web/Views/ViewLuggageTransporter.cs @@ -0,0 +1,32 @@ +using System.Collections; +using System.Web; + +namespace Marina.Web.Views { + public class ViewLuggageTransporter< Luggage > : IViewLuggageTransporter< Luggage > { + public ViewLuggageTransporter( IViewLuggageTicket< Luggage > key ) : this( key, HttpContext.Current.Items ) {} + + private ViewLuggageTransporter( IViewLuggageTicket< Luggage > key, IDictionary items ) { + _ticket = key; + _items = items; + } + + public Luggage Value() { + foreach ( DictionaryEntry entry in _items ) { + if ( entry.Value is Luggage ) { + return ( Luggage )entry.Value; + } + //if ( entry.Key.Equals( _ticket ) ) { + // return ( Luggage )entry.Value; + //} + } + return default( Luggage ); + } + + public void Add( Luggage value ) { + _items.Add( _ticket, value ); + } + + private readonly IViewLuggageTicket< Luggage > _ticket; + private readonly IDictionary _items; + } +} \ No newline at end of file diff --git a/slips/src/app/Marina/Web/Views/WebView.cs b/slips/src/app/Marina/Web/Views/WebView.cs new file mode 100644 index 0000000..f517479 --- /dev/null +++ b/slips/src/app/Marina/Web/Views/WebView.cs @@ -0,0 +1,27 @@ +using Marina.Web.Http; + +namespace Marina.Web.Views { + public class WebView< T > : IWebView< T > { + public WebView( string name, IViewLuggageTransporter< T > viewBag, IHttpGateway gateway ) { + this.name = name; + this.gateway = gateway; + this.viewBag = viewBag; + } + + public string Name() { + return name; + } + + public void Render() { + gateway.RedirectTo( this ); + } + + public void AddToBag( T slips ) { + viewBag.Add( slips ); + } + + private readonly string name; + private readonly IHttpGateway gateway; + private readonly IViewLuggageTransporter< T > viewBag; + } +} \ No newline at end of file diff --git a/slips/src/app/Marina/Web/Views/WebViews.cs b/slips/src/app/Marina/Web/Views/WebViews.cs new file mode 100644 index 0000000..6431606 --- /dev/null +++ b/slips/src/app/Marina/Web/Views/WebViews.cs @@ -0,0 +1,18 @@ +using Marina.Web.Views.Pages; + +namespace Marina.Web.Views { + public class WebViews { + public static readonly IAvailableSlipsWebView AvailableSlips = new AvailableSlipsWebView( ); + + public static readonly IView ContactUs = new View( "ContactUs.aspx" ); + public static readonly IView Default = new View( "Default.aspx" ); + public static readonly IView DockView = new View( "DockView.aspx" ); + public static readonly IView Login = new View( "Login.aspx" ); + public static readonly IView RegisterBoat = new View( "RegisterBoat.aspx" ); + public static readonly IView Registration = new View( "Registration.aspx" ); + public static readonly IView UpdateCustomerRegistration = new View( "UpdateCustomerRegistration.aspx" ); + public static readonly IView ViewRegisteredBoats = new View( "ViewRegisteredBoats.aspx" ); + public static readonly IView CurrentLeases = new View( "CurrentLeases.aspx" ); + public static readonly IView LeaseSlip = new View( "LeaseSlip.aspx" ); + } +} \ No newline at end of file diff --git a/slips/src/test/Marina.Test/Integration/DataAccess/Mappers/BoatDataMapperTest.cs b/slips/src/test/Marina.Test/Integration/DataAccess/Mappers/BoatDataMapperTest.cs new file mode 100644 index 0000000..20b881f --- /dev/null +++ b/slips/src/test/Marina.Test/Integration/DataAccess/Mappers/BoatDataMapperTest.cs @@ -0,0 +1,78 @@ +using System; +using System.Collections.Generic; +using Marina.DataAccess.DataMappers; +using Marina.Domain; +using Marina.Domain.Interfaces; +using Marina.Infrastructure; +using Marina.Test.Integration.DataAccess.Utility; +using Marina.Test.Utility; +using MbUnit.Framework; + +namespace Marina.Test.Integration.DataAccess.Mappers { + [TestFixture] + public class BoatDataMapperTest { + public IBoatDataMapper CreateSUT() { + return new BoatDataMapper( ); + } + + [Test] + [RunInRealContainer] + [RollBack] + public void Should_return_3_boats() { + long customerId = CustomerMother.CreateCustomerRecord( ); + + BoatMother.AddBoatsFor( customerId ); + + IRichList< IBoat > boats = ListFactory.From( CreateSUT( ).AllBoatsFor( customerId ) ); + Assert.AreEqual( 3, boats.Count ); + } + + [Test] + [RunInRealContainer] + [RollBack] + public void Should_be_able_to_insert_new_boats_for_customer() { + IBoat firstBoat = new Boat( "reg1", "TOYOTA", new DateTime( 2001, 1, 1 ), 100 ); + IBoat secondBoat = new Boat( "reg2", "YAMAHA", new DateTime( 2005, 1, 1 ), 200 ); + + IList< IBoat > boats = new List< IBoat >( ); + boats.Add( firstBoat ); + boats.Add( secondBoat ); + + long customerId = CustomerMother.CreateCustomerRecord( ); + IBoatDataMapper mapper = CreateSUT( ); + mapper.Insert( boats, customerId ); + + IRichList< IBoat > insertedBoats = ListFactory.From( mapper.AllBoatsFor( customerId ) ); + Assert.AreEqual( 2, insertedBoats.Count ); + Assert.IsTrue( insertedBoats.Contains( firstBoat ) ); + Assert.IsTrue( insertedBoats.Contains( secondBoat ) ); + } + + [Test] + [RollBack] + [RunInRealContainer] + public void Should_insert_new_boats_for_customer() { + long customerId = CustomerMother.CreateCustomerRecord( ); + IList< IBoat > boats = CreateBoats( ); + + IBoatDataMapper mapper = CreateSUT( ); + mapper.Insert( boats, customerId ); + + IBoat thirdBoat = new Boat( "reg3", "HONDA", new DateTime( 1999, 1, 1 ), 300 ); + boats.Add( thirdBoat ); + + mapper.Update( boats, customerId ); + + IRichList< IBoat > insertedBoats = ListFactory.From( mapper.AllBoatsFor( customerId ) ); + Assert.AreEqual( 3, insertedBoats.Count ); + Assert.IsTrue( insertedBoats.Contains( thirdBoat ) ); + } + + private IList< IBoat > CreateBoats() { + IList< IBoat > boats = new List< IBoat >( ); + boats.Add( new Boat( "reg1", "TOYOTA", new DateTime( 2001, 1, 1 ), 100 ) ); + boats.Add( new Boat( "reg2", "YAMAHA", new DateTime( 2005, 1, 1 ), 200 ) ); + return boats; + } + } +} \ No newline at end of file diff --git a/slips/src/test/Marina.Test/Integration/DataAccess/Mappers/CustomerDataMapperTest.cs b/slips/src/test/Marina.Test/Integration/DataAccess/Mappers/CustomerDataMapperTest.cs new file mode 100644 index 0000000..ef32eac --- /dev/null +++ b/slips/src/test/Marina.Test/Integration/DataAccess/Mappers/CustomerDataMapperTest.cs @@ -0,0 +1,25 @@ +using Marina.DataAccess.DataMappers; +using Marina.Domain.Interfaces; +using Marina.Test.Integration.DataAccess.Utility; +using Marina.Test.Utility; +using MbUnit.Framework; + +namespace Marina.Test.Integration.DataAccess.Mappers { + public class CustomerDataMapperTest { + public ICustomerDataMapper CreateSUT() { + return new CustomerDataMapper( ); + } + + [Test] + [RollBack] + [RunInRealContainer] + public void Should_be_able_to_find_customer_by_username() { + string username = "mokhan"; + long customerId = CustomerMother.CreateCustomerRecordWith( username ); + + ICustomer foundCustomer = CreateSUT( ).FindBy( username ); + Assert.AreEqual( customerId, foundCustomer.ID( ) ); + Assert.AreEqual( username, foundCustomer.Registration( ).Username( ) ); + } + } +} \ No newline at end of file diff --git a/slips/src/test/Marina.Test/Integration/DataAccess/Mappers/LeaseDataMapperTest.cs b/slips/src/test/Marina.Test/Integration/DataAccess/Mappers/LeaseDataMapperTest.cs new file mode 100644 index 0000000..c08577e --- /dev/null +++ b/slips/src/test/Marina.Test/Integration/DataAccess/Mappers/LeaseDataMapperTest.cs @@ -0,0 +1,44 @@ +using System.Collections.Generic; +using Marina.DataAccess.DataMappers; +using Marina.Domain; +using Marina.Domain.Interfaces; +using Marina.Infrastructure; +using Marina.Test.Integration.DataAccess.Utility; +using Marina.Test.Utility; +using MbUnit.Framework; + +namespace Marina.Test.Integration.DataAccess.Mappers { + [TestFixture] + public class LeaseDataMapperTest { + public ILeaseDataMapper CreateSUT() { + return new LeaseDataMapper( ); + } + + [Test] + [RollBack] + [RunInRealContainer] + public void Should_return_all_leases_for_a_specific_customer() { + long customerId = CustomerMother.CreateCustomerRecord( ); + LeaseMother.CreateLeaseFor( customerId ); + + IRichList< ISlipLease > leasesForCustomer = ListFactory.From( CreateSUT( ).AllLeasesFor( customerId ) ); + Assert.AreEqual( 1, leasesForCustomer.Count ); + } + + [Test] + [RollBack] + [RunInRealContainer] + public void Should_be_able_to_insert_new_leases_for_customer() { + long customerId = CustomerMother.CreateCustomerRecord( ); + + IList< ISlipLease > leases = new List< ISlipLease >( ); + leases.Add( new SlipLease( new Slip( 1000, null, 100, 100, true ), LeaseDurations.Daily ) ); + + ILeaseDataMapper mapper = CreateSUT( ); + mapper.Insert( leases, customerId ); + + IRichList< ISlipLease > foundLeases = ListFactory.From( mapper.AllLeasesFor( customerId ) ); + Assert.AreEqual( 1, foundLeases.Count ); + } + } +} \ No newline at end of file diff --git a/slips/src/test/Marina.Test/Integration/DataAccess/Mappers/RegistrationDataMapperTest.cs b/slips/src/test/Marina.Test/Integration/DataAccess/Mappers/RegistrationDataMapperTest.cs new file mode 100644 index 0000000..d4beabf --- /dev/null +++ b/slips/src/test/Marina.Test/Integration/DataAccess/Mappers/RegistrationDataMapperTest.cs @@ -0,0 +1,70 @@ +using Marina.DataAccess; +using Marina.DataAccess.Builders; +using Marina.DataAccess.DataMappers; +using Marina.DataAccess.Schemas; +using Marina.Domain; +using Marina.Domain.Interfaces; +using Marina.Infrastructure.Container; +using Marina.Test.Utility; +using MbUnit.Framework; + +namespace Marina.Test.Integration.DataAccess.Mappers { + [TestFixture] + public class RegistrationDataMapperTest { + public IRegistrationDataMapper CreateSUT() { + return new RegistrationDataMapper( ); + } + + [RunInRealContainer] + [Test] + public void Should_be_able_to_find_john() { + int customerId = 1000; + IRegistration registration = CreateSUT( ).For( customerId ); + Assert.AreEqual( "John", registration.FirstName( ) ); + Assert.AreEqual( "Doe", registration.LastName( ) ); + Assert.AreEqual( "555-545-1212", registration.PhoneNumber( ) ); + Assert.AreEqual( "Phoenix", registration.City( ) ); + } + + [RunInRealContainer] + [Test] + [RollBack] + public void Should_be_able_to_insert_new_registration_for_customer() { + IRegistrationDataMapper mapper = CreateSUT( ); + long customerId = CreateCustomerRecord( ); + IRegistration expectedRegistration = + new CustomerRegistration( "mokhan", "password", "mo", "khan", "4036813389", "calgary" ); + + mapper.Insert( expectedRegistration, customerId ); + IRegistration actualRegistration = mapper.For( customerId ); + Assert.AreEqual( expectedRegistration, actualRegistration ); + } + + [RunInRealContainer] + [Test] + [RollBack] + public void Should_be_able_to_update_record() { + IRegistrationDataMapper mapper = CreateSUT( ); + long customerId = CreateCustomerRecord( ); + IRegistration firstRegistration = + new CustomerRegistration( "mokhan", "password", "mo", "khan", "4036813389", "calgary" ); + IRegistration expectedRegistration = + new CustomerRegistration( "khanmo", "wordpass", "om", "ankh", "1338940368", "garycal" ); + + mapper.Insert( firstRegistration, customerId ); + mapper.Update( expectedRegistration, customerId ); + + IRegistration actualRegistration = mapper.For( customerId ); + Assert.AreEqual( expectedRegistration, actualRegistration ); + } + + private long CreateCustomerRecord() { + IQuery query = DatabaseInsert.Into( CustomerTable.TableName ) + .AddValue( CustomerTable.FirstName, string.Empty ) + .AddValue( CustomerTable.LastName, string.Empty ) + .AddValue( CustomerTable.Phone, string.Empty ) + .AddValue( CustomerTable.City, string.Empty ).Build( ); + return Resolve.DependencyFor< IDatabaseGateway >( ).ExecuteScalar( query ); + } + } +} \ No newline at end of file diff --git a/slips/src/test/Marina.Test/Integration/DataAccess/Repositories/DockRepositoryTest.cs b/slips/src/test/Marina.Test/Integration/DataAccess/Repositories/DockRepositoryTest.cs new file mode 100644 index 0000000..7612f50 --- /dev/null +++ b/slips/src/test/Marina.Test/Integration/DataAccess/Repositories/DockRepositoryTest.cs @@ -0,0 +1,24 @@ +using Marina.DataAccess.Repositories; +using Marina.Domain.Interfaces; +using Marina.Domain.Repositories; +using Marina.Test.Utility; +using MbUnit.Framework; + +namespace Marina.Test.Integration.DataAccess.Repositories { + [TestFixture] + public class DockRepositoryTest { + public IDockRepository CreateSUT() { + return new DockRepository( ); + } + + [RunInRealContainer] + [RowTest] + [Row( 1 )] + [Row( 2 )] + [Row( 3 )] + public void Should_load_dock_by( long dockId ) { + IDock dock = CreateSUT( ).FindBy( dockId ); + Assert.AreEqual( dockId, dock.ID( ) ); + } + } +} \ No newline at end of file diff --git a/slips/src/test/Marina.Test/Integration/DataAccess/Repositories/SlipRepositoryTest.cs b/slips/src/test/Marina.Test/Integration/DataAccess/Repositories/SlipRepositoryTest.cs new file mode 100644 index 0000000..ab4b907 --- /dev/null +++ b/slips/src/test/Marina.Test/Integration/DataAccess/Repositories/SlipRepositoryTest.cs @@ -0,0 +1,32 @@ +using Marina.DataAccess.Repositories; +using Marina.Domain; +using Marina.Domain.Interfaces; +using Marina.Domain.Repositories; +using Marina.Infrastructure; +using Marina.Test.Utility; +using MbUnit.Framework; + +namespace Marina.Test.Integration.DataAccess.Repositories { + [TestFixture] + public class SlipRepositoryTest { + public ISlipsRepository CreateSUT() { + return new SlipsRepository( ); + } + + [RunInRealContainer] + [Test] + public void Should_return_at_least_one_available_slip() { + Assert.IsTrue( ListFactory.From( CreateSUT( ).AllAvailableSlips( ) ).Count > 0 ); + } + + [RunInRealContainer] + [Test] + public void Should_return_at_least_one_available_slip_for_the_dock() { + ISlipsRepository repository = CreateSUT( ); + IDock dock = new Dock( 1, string.Empty, null, null ); + + IRichList< ISlip > slipsFound = ListFactory.From( repository.AllAvailableSlipsFor( dock ) ); + Assert.IsTrue( slipsFound.Count > 0 ); + } + } +} \ No newline at end of file diff --git a/slips/src/test/Marina.Test/Integration/DataAccess/Utility/BoatMother.cs b/slips/src/test/Marina.Test/Integration/DataAccess/Utility/BoatMother.cs new file mode 100644 index 0000000..cb8d7b3 --- /dev/null +++ b/slips/src/test/Marina.Test/Integration/DataAccess/Utility/BoatMother.cs @@ -0,0 +1,19 @@ +using Marina.DataAccess; +using Marina.DataAccess.Builders; +using Marina.DataAccess.Schemas; +using Marina.Infrastructure.Container; + +namespace Marina.Test.Integration.DataAccess.Utility { + public static class BoatMother { + public static void AddBoatsFor( long customerId ) { + IInsertQueryBuilder builder = DatabaseInsert.Into( BoatTable.TableName ) + .AddValue( BoatTable.RegistrationNumber, string.Empty ) + .AddValue( BoatTable.Manufacturer, string.Empty ) + .AddValue( BoatTable.ModelYear, string.Empty ) + .AddValue( BoatTable.Length, string.Empty ) + .AddValue( BoatTable.CustomerID, customerId.ToString( ) ); + + Resolve.DependencyFor< IDatabaseGateway >( ).Execute( builder.Build( ), builder.Build( ), builder.Build( ) ); + } + } +} \ No newline at end of file diff --git a/slips/src/test/Marina.Test/Integration/DataAccess/Utility/CustomerMother.cs b/slips/src/test/Marina.Test/Integration/DataAccess/Utility/CustomerMother.cs new file mode 100644 index 0000000..923528a --- /dev/null +++ b/slips/src/test/Marina.Test/Integration/DataAccess/Utility/CustomerMother.cs @@ -0,0 +1,34 @@ +using Marina.DataAccess; +using Marina.DataAccess.Builders; +using Marina.DataAccess.Schemas; +using Marina.Infrastructure.Container; + +namespace Marina.Test.Integration.DataAccess.Utility { + public static class CustomerMother { + public static long CreateCustomerRecord() { + IInsertQueryBuilder builder = DatabaseInsert.Into( CustomerTable.TableName ) + .AddValue( CustomerTable.FirstName, string.Empty ) + .AddValue( CustomerTable.LastName, string.Empty ) + .AddValue( CustomerTable.Phone, string.Empty ) + .AddValue( CustomerTable.City, string.Empty ); + return Resolve.DependencyFor< IDatabaseGateway >( ).ExecuteScalar( builder.Build( ) ); + } + + public static long CreateCustomerRecordWith( string username ) { + IInsertQueryBuilder builder = DatabaseInsert.Into( CustomerTable.TableName ) + .AddValue( CustomerTable.FirstName, string.Empty ) + .AddValue( CustomerTable.LastName, string.Empty ) + .AddValue( CustomerTable.Phone, string.Empty ) + .AddValue( CustomerTable.City, string.Empty ); + long customerId = Resolve.DependencyFor< IDatabaseGateway >( ).ExecuteScalar( builder.Build( ) ); + + IQuery insertToAuthTable = DatabaseInsert.Into( AuthorizationTable.TableName ) + .AddValue( AuthorizationTable.UserName, username ) + .AddValue( AuthorizationTable.Password, string.Empty ) + .Build( ); + + Resolve.DependencyFor< IDatabaseGateway >( ).Execute( insertToAuthTable ); + return customerId; + } + } +} \ No newline at end of file diff --git a/slips/src/test/Marina.Test/Integration/DataAccess/Utility/LeaseMother.cs b/slips/src/test/Marina.Test/Integration/DataAccess/Utility/LeaseMother.cs new file mode 100644 index 0000000..1c8b2ec --- /dev/null +++ b/slips/src/test/Marina.Test/Integration/DataAccess/Utility/LeaseMother.cs @@ -0,0 +1,21 @@ +using System; +using Marina.DataAccess; +using Marina.DataAccess.Builders; +using Marina.DataAccess.Schemas; +using Marina.Infrastructure.Container; + +namespace Marina.Test.Integration.DataAccess.Utility { + public static class LeaseMother { + public static void CreateLeaseFor( long customerId ) { + IQuery query = DatabaseInsert + .Into( LeaseTable.TableName ) + .AddValue( LeaseTable.CustomerID, customerId ) + .AddValue( LeaseTable.EndDate, DateTime.Now.AddDays( 1 ) ) + .AddValue( LeaseTable.LeaseTypeID, 1 ) + .AddValue( LeaseTable.SlipID, SlipMother.CreateSlip( ) ) + .AddValue( LeaseTable.StartDate, DateTime.Now ).Build( ); + + Resolve.DependencyFor< IDatabaseGateway >( ).Execute( query ); + } + } +} \ No newline at end of file diff --git a/slips/src/test/Marina.Test/Integration/DataAccess/Utility/SlipMother.cs b/slips/src/test/Marina.Test/Integration/DataAccess/Utility/SlipMother.cs new file mode 100644 index 0000000..51cbecb --- /dev/null +++ b/slips/src/test/Marina.Test/Integration/DataAccess/Utility/SlipMother.cs @@ -0,0 +1,18 @@ +using Marina.DataAccess; +using Marina.DataAccess.Builders; +using Marina.DataAccess.Schemas; +using Marina.Infrastructure.Container; + +namespace Marina.Test.Integration.DataAccess.Utility { + public static class SlipMother { + public static long CreateSlip() { + IQuery query = DatabaseInsert + .Into( SlipTable.TableName ) + .AddValue( SlipTable.DockID, 1 ) + .AddValue( SlipTable.Length, 100 ) + .AddValue( SlipTable.Width, 100 ).Build( ); + + return Resolve.DependencyFor< IDatabaseGateway >( ).ExecuteScalar( query ); + } + } +} \ No newline at end of file diff --git a/slips/src/test/Marina.Test/Integration/Task/CatalogTasksTest.cs b/slips/src/test/Marina.Test/Integration/Task/CatalogTasksTest.cs new file mode 100644 index 0000000..fc5e09e --- /dev/null +++ b/slips/src/test/Marina.Test/Integration/Task/CatalogTasksTest.cs @@ -0,0 +1,19 @@ +using Marina.Infrastructure; +using Marina.Task; +using Marina.Test.Utility; +using MbUnit.Framework; + +namespace Marina.Test.Integration.Task { + [TestFixture] + public class CatalogTasksTest { + public ICatalogTasks CreateSUT() { + return new CatalogTasks( ); + } + + [RunInRealContainer] + [Test] + public void Should_return_at_least_one_available_slip() { + Assert.IsTrue( ListFactory.From( CreateSUT( ).GetAllAvailableSlips( ) ).Count > 0 ); + } + } +} \ No newline at end of file diff --git a/slips/src/test/Marina.Test/Marina.Test.csproj b/slips/src/test/Marina.Test/Marina.Test.csproj new file mode 100644 index 0000000..f06e22f --- /dev/null +++ b/slips/src/test/Marina.Test/Marina.Test.csproj @@ -0,0 +1,136 @@ + + + + Debug + AnyCPU + 9.0.21022 + 2.0 + {D9BCEEBA-F4D1-4057-8070-5EB1640D618D} + Library + Properties + Marina.Test + Marina.Test + v3.5 + 512 + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + False + ..\..\..\build\lib\log4net\bin\log4net.dll + + + False + ..\..\..\build\tools\mbunit\bin\MbUnit.Framework.dll + + + False + ..\..\..\build\tools\rhino.mocks\bin\Rhino.Mocks.dll + + + + + 3.5 + + + + 3.5 + + + 3.5 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {F9AF658A-2A26-49DE-A964-7A846A8DCC2A} + Marina + + + + + + + + + \ No newline at end of file diff --git a/slips/src/test/Marina.Test/Properties/AssemblyInfo.cs b/slips/src/test/Marina.Test/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..1d1a117 --- /dev/null +++ b/slips/src/test/Marina.Test/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("Marina.Test")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("Marina.Test")] +[assembly: AssemblyCopyright("Copyright © 2007")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("fe5b2656-dda1-4db6-8bd4-e0c467729b9f")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/slips/src/test/Marina.Test/Unit/DataAccess/DatabaseCommandTest.cs b/slips/src/test/Marina.Test/Unit/DataAccess/DatabaseCommandTest.cs new file mode 100644 index 0000000..c08b272 --- /dev/null +++ b/slips/src/test/Marina.Test/Unit/DataAccess/DatabaseCommandTest.cs @@ -0,0 +1,48 @@ +using System.Data; +using Marina.DataAccess; +using MbUnit.Framework; +using Rhino.Mocks; + +namespace Marina.Test.Unit.DataAccess { + [TestFixture] + public class DatabaseCommandTest { + private MockRepository _mockery; + private IDbCommand _mockCommand; + + [SetUp] + public void Setup() { + _mockery = new MockRepository( ); + _mockCommand = _mockery.DynamicMock< IDbCommand >( ); + } + + public IDatabaseCommand CreateSUT() { + return new DatabaseCommand( _mockCommand ); + } + + [Test] + public void Should_execute_the_command() { + IDataReader mockReader = _mockery.DynamicMock< IDataReader >( ); + + using ( _mockery.Record( ) ) { + Expect.Call( _mockCommand.ExecuteReader( ) ).Return( mockReader ); + } + + using ( _mockery.Playback( ) ) { + CreateSUT( ).ExecuteQuery( ); + } + } + + [Test] + public void Should_return_a_loaded_data_table() { + IDataReader mockReader = _mockery.DynamicMock< IDataReader >( ); + + using ( _mockery.Record( ) ) { + SetupResult.For( _mockCommand.ExecuteReader( ) ).Return( mockReader ); + } + + using ( _mockery.Playback( ) ) { + Assert.IsNotNull( CreateSUT( ).ExecuteQuery( ) ); + } + } + } +} \ No newline at end of file diff --git a/slips/src/test/Marina.Test/Unit/DataAccess/DatabaseConfigurationTest.cs b/slips/src/test/Marina.Test/Unit/DataAccess/DatabaseConfigurationTest.cs new file mode 100644 index 0000000..3dc2d1f --- /dev/null +++ b/slips/src/test/Marina.Test/Unit/DataAccess/DatabaseConfigurationTest.cs @@ -0,0 +1,33 @@ +using System.Configuration; +using Marina.DataAccess; +using MbUnit.Framework; + +namespace Marina.Test.Unit.DataAccess { + [TestFixture] + public class DatabaseConfigurationTest { + private ConnectionStringSettings _settings; + + [SetUp] + public void Setup() { + _settings = new ConnectionStringSettings( "ConnectionName", string.Empty, string.Empty ); + } + + public IDatabaseConfiguration CreateSUT() { + return new DatabaseConfiguration( _settings ); + } + + [Test] + public void Should_return_connection_string() { + string connectionString = "MyConnectionString"; + _settings.ConnectionString = connectionString; + Assert.AreEqual( connectionString, CreateSUT( ).ConnectionString( ) ); + } + + [Test] + public void Should_return_the_provider_name() { + string providerName = "MyProvider"; + _settings.ProviderName = providerName; + Assert.AreEqual( providerName, CreateSUT( ).ProviderName( ) ); + } + } +} \ No newline at end of file diff --git a/slips/src/test/Marina.Test/Unit/DataAccess/DatabaseConnectionTest.cs b/slips/src/test/Marina.Test/Unit/DataAccess/DatabaseConnectionTest.cs new file mode 100644 index 0000000..8cd8ec1 --- /dev/null +++ b/slips/src/test/Marina.Test/Unit/DataAccess/DatabaseConnectionTest.cs @@ -0,0 +1,167 @@ +using System.Data; +using Marina.DataAccess; +using MbUnit.Framework; +using Rhino.Mocks; + +namespace Marina.Test.Unit.DataAccess { + [TestFixture] + public class DatabaseConnectionTest { + private MockRepository _mockery; + private IDatabaseConfiguration _mockConfiguration; + private IDatabaseProviderFactory _mockProviderFactory; + + [SetUp] + public void Setup() { + _mockery = new MockRepository( ); + _mockConfiguration = _mockery.DynamicMock< IDatabaseConfiguration >( ); + _mockProviderFactory = _mockery.DynamicMock< IDatabaseProviderFactory >( ); + } + + public IDatabaseConnection CreateSUT() { + return new DatabaseConnection( _mockConfiguration, _mockProviderFactory ); + } + + [Test] + public void Should_create_connection_for_provider_name() { + string providerName = "System.Data.SqlClient"; + + IDbConnection mockConnection = _mockery.DynamicMock< IDbConnection >( ); + using ( _mockery.Record( ) ) { + SetupResult.For( _mockConfiguration.ProviderName( ) ).Return( providerName ); + + Expect.Call( _mockProviderFactory.CreateConnectionFor( providerName ) ).Return( mockConnection ); + } + + using ( _mockery.Playback( ) ) { + CreateSUT( ).CreateCommandFor( "" ); + } + } + + [RowTest] + [Row( "MyConnectionString" )] + [Row( "MyStringOfConnection" )] + [Row( "MyConnectionString3" )] + public void Should_set_the_connections_connection_string_to( string connectionString ) { + string providerName = "System.Data.SqlClient"; + + IDbConnection mockConnection = _mockery.DynamicMock< IDbConnection >( ); + using ( _mockery.Record( ) ) { + SetupResult.For( _mockConfiguration.ConnectionString( ) ).Return( connectionString ); + SetupResult.For( _mockConfiguration.ProviderName( ) ).Return( providerName ); + SetupResult.For( _mockProviderFactory.CreateConnectionFor( providerName ) ).Return( mockConnection ); + + mockConnection.ConnectionString = connectionString; + } + + using ( _mockery.Playback( ) ) { + CreateSUT( ).CreateCommandFor( "" ); + } + } + + [Test] + public void Should_create_a_command_object_using_the_connection() { + string providerName = "System.Data.SqlClient"; + string connectionString = "MyConnectionString"; + + IDbConnection mockConnection = _mockery.DynamicMock< IDbConnection >( ); + IDbCommand mockCommand = _mockery.DynamicMock< IDbCommand >( ); + + using ( _mockery.Record( ) ) { + SetupResult.For( _mockConfiguration.ConnectionString( ) ).Return( connectionString ); + SetupResult.For( _mockConfiguration.ProviderName( ) ).Return( providerName ); + SetupResult.For( _mockProviderFactory.CreateConnectionFor( providerName ) ).Return( mockConnection ); + + Expect.Call( mockConnection.CreateCommand( ) ).Return( mockCommand ); + } + + using ( _mockery.Playback( ) ) { + CreateSUT( ).CreateCommandFor( "" ); + } + } + + [RowTest] + [Row( "Select * From Auctions" )] + [Row( "Select * From Pets" )] + public void Should_set_the_commands_text_and_type( string sqlQuery ) { + string providerName = "System.Data.SqlClient"; + string connectionString = "MyConnectionString"; + + IDbConnection mockConnection = _mockery.DynamicMock< IDbConnection >( ); + IDbCommand mockCommand = _mockery.DynamicMock< IDbCommand >( ); + + using ( _mockery.Record( ) ) { + SetupResult.For( _mockConfiguration.ConnectionString( ) ).Return( connectionString ); + SetupResult.For( _mockConfiguration.ProviderName( ) ).Return( providerName ); + SetupResult.For( _mockProviderFactory.CreateConnectionFor( providerName ) ).Return( mockConnection ); + SetupResult.For( mockConnection.CreateCommand( ) ).Return( mockCommand ); + + mockCommand.CommandText = sqlQuery; + mockCommand.CommandType = CommandType.Text; + } + + using ( _mockery.Playback( ) ) { + CreateSUT( ).CreateCommandFor( sqlQuery ); + } + } + + [Test] + public void Should_return_new_database_command() { + string providerName = "System.Data.SqlClient"; + string connectionString = "MyConnectionString"; + + IDbConnection mockConnection = _mockery.DynamicMock< IDbConnection >( ); + IDbCommand mockCommand = _mockery.DynamicMock< IDbCommand >( ); + + using ( _mockery.Record( ) ) { + SetupResult.For( _mockConfiguration.ConnectionString( ) ).Return( connectionString ); + SetupResult.For( _mockConfiguration.ProviderName( ) ).Return( providerName ); + SetupResult.For( _mockProviderFactory.CreateConnectionFor( providerName ) ).Return( mockConnection ); + SetupResult.For( mockConnection.CreateCommand( ) ).Return( mockCommand ); + } + + using ( _mockery.Playback( ) ) { + Assert.IsNotNull( CreateSUT( ).CreateCommandFor( "" ) ); + } + } + + [Test] + public void Should_close_connection_when_disposed() { + string providerName = "System.Data.SqlClient"; + string connectionString = "MyConnectionString"; + + IDbConnection mockConnection = _mockery.DynamicMock< IDbConnection >( ); + + using ( _mockery.Record( ) ) { + SetupResult.For( _mockConfiguration.ConnectionString( ) ).Return( connectionString ); + SetupResult.For( _mockConfiguration.ProviderName( ) ).Return( providerName ); + SetupResult.For( _mockProviderFactory.CreateConnectionFor( providerName ) ).Return( mockConnection ); + + mockConnection.Close( ); + } + + using ( _mockery.Playback( ) ) { + CreateSUT( ).Dispose( ); + } + } + + [Test] + public void Should_open_connection_when_created() { + string providerName = "System.Data.SqlClient"; + string connectionString = "MyConnectionString"; + + IDbConnection mockConnection = _mockery.DynamicMock< IDbConnection >( ); + + using ( _mockery.Record( ) ) { + SetupResult.For( _mockConfiguration.ConnectionString( ) ).Return( connectionString ); + SetupResult.For( _mockConfiguration.ProviderName( ) ).Return( providerName ); + SetupResult.For( _mockProviderFactory.CreateConnectionFor( providerName ) ).Return( mockConnection ); + + mockConnection.Open( ); + } + + using ( _mockery.Playback( ) ) { + CreateSUT( ); + } + } + } +} \ No newline at end of file diff --git a/slips/src/test/Marina.Test/Unit/DataAccess/DatabaseGatewayTest.cs b/slips/src/test/Marina.Test/Unit/DataAccess/DatabaseGatewayTest.cs new file mode 100644 index 0000000..f53d1ec --- /dev/null +++ b/slips/src/test/Marina.Test/Unit/DataAccess/DatabaseGatewayTest.cs @@ -0,0 +1,91 @@ +using System.Data; +using Marina.DataAccess; +using MbUnit.Framework; +using Rhino.Mocks; + +namespace Marina.Test.Unit.DataAccess { + [TestFixture] + public class DatabaseGatewayTest { + private MockRepository _mockery; + private IDatabaseConnectionFactory _mockConnectionFactory; + + [SetUp] + public void Setup() { + _mockery = new MockRepository( ); + _mockConnectionFactory = _mockery.DynamicMock< IDatabaseConnectionFactory >( ); + } + + public IDatabaseGateway CreateSUT() { + return new DatabaseGateway( _mockConnectionFactory ); + } + + [Test] + public void Should_leverage_factory_to_create_a_new_connection() { + IDatabaseConnection mockConnection = _mockery.DynamicMock< IDatabaseConnection >( ); + using ( _mockery.Record( ) ) { + Expect.Call( _mockConnectionFactory.Create( ) ).Return( mockConnection ); + } + + using ( _mockery.Playback( ) ) { + CreateSUT( ).LoadTableUsing( "" ); + } + } + + [Test] + public void Should_create_command_using_database_connection() { + IDatabaseConnection mockConnection = _mockery.DynamicMock< IDatabaseConnection >( ); + IDatabaseCommand mockCommand = _mockery.DynamicMock< IDatabaseCommand >( ); + string sqlQuery = "SELECT * FROM ?"; + + using ( _mockery.Record( ) ) { + SetupResult.For( _mockConnectionFactory.Create( ) ).Return( mockConnection ); + Expect.Call( mockConnection.CreateCommandFor( sqlQuery ) ).Return( mockCommand ); + } + + using ( _mockery.Playback( ) ) { + CreateSUT( ).LoadTableUsing( sqlQuery ); + } + } + + [RowTest] + [Row( "SELECT * FROM Cars" )] + [Row( "SELECT * FROM Persons" )] + public void Should_execute_query_on_command( string sqlQuery ) { + IDatabaseConnection mockConnection = _mockery.DynamicMock< IDatabaseConnection >( ); + IDatabaseCommand mockCommand = _mockery.DynamicMock< IDatabaseCommand >( ); + + DataTable table = new DataTable( ); + using ( _mockery.Record( ) ) { + SetupResult.For( _mockConnectionFactory.Create( ) ).Return( mockConnection ); + SetupResult.For( mockConnection.CreateCommandFor( sqlQuery ) ).Return( mockCommand ); + Expect.Call( mockCommand.ExecuteQuery( ) ).Return( table ); + } + + using ( _mockery.Playback( ) ) { + Assert.AreEqual( table, CreateSUT( ).LoadTableUsing( sqlQuery ) ); + } + } + + [Test] + public void Should_close_the_connection_after_executing_the_command() { + IDatabaseConnection mockConnection = _mockery.DynamicMock< IDatabaseConnection >( ); + IDatabaseCommand mockCommand = _mockery.DynamicMock< IDatabaseCommand >( ); + string sqlQuery = "SELECT * FROM ?"; + + DataTable table = new DataTable( ); + using ( _mockery.Record( ) ) { + SetupResult.For( _mockConnectionFactory.Create( ) ).Return( mockConnection ); + SetupResult.For( mockConnection.CreateCommandFor( sqlQuery ) ).Return( mockCommand ); + + using ( _mockery.Ordered( ) ) { + Expect.Call( mockCommand.ExecuteQuery( ) ).Return( table ); + mockConnection.Dispose( ); + } + } + + using ( _mockery.Playback( ) ) { + CreateSUT( ).LoadTableUsing( sqlQuery ); + } + } + } +} \ No newline at end of file diff --git a/slips/src/test/Marina.Test/Unit/DataAccess/Mappers/CustomerDataMapperTest.cs b/slips/src/test/Marina.Test/Unit/DataAccess/Mappers/CustomerDataMapperTest.cs new file mode 100644 index 0000000..81e170b --- /dev/null +++ b/slips/src/test/Marina.Test/Unit/DataAccess/Mappers/CustomerDataMapperTest.cs @@ -0,0 +1,86 @@ +using System.Collections.Generic; +using Marina.DataAccess; +using Marina.DataAccess.DataMappers; +using Marina.Domain.Interfaces; +using Marina.Infrastructure; +using MbUnit.Framework; +using Rhino.Mocks; + +namespace Marina.Test.Unit.DataAccess.Mappers { + [TestFixture] + public class CustomerDataMapperTest { + private MockRepository _mockery; + private IDatabaseGateway _mockGateway; + private IBoatDataMapper _boatMapper; + private ILeaseDataMapper _leaseDataMapper; + private IRegistrationDataMapper _registrationMapper; + + [SetUp] + public void Setup() { + _mockery = new MockRepository( ); + _mockGateway = _mockery.DynamicMock< IDatabaseGateway >( ); + _boatMapper = _mockery.DynamicMock< IBoatDataMapper >( ); + _leaseDataMapper = _mockery.DynamicMock< ILeaseDataMapper >( ); + _registrationMapper = _mockery.DynamicMock< IRegistrationDataMapper >( ); + } + + public ICustomerDataMapper CreateSUT() { + return new CustomerDataMapper( _mockGateway, _boatMapper, _leaseDataMapper, _registrationMapper ); + } + + [Test] + public void Should_leverage_mapper_to_load_customers_boats() { + long customerId = 32; + + IList< IBoat > boats = new List< IBoat >( ); + IBoat boat = _mockery.DynamicMock< IBoat >( ); + boats.Add( boat ); + + using ( _mockery.Record( ) ) { + Expect.Call( _boatMapper.AllBoatsFor( customerId ) ).Return( boats ); + } + + using ( _mockery.Playback( ) ) { + ICustomer customer = CreateSUT( ).FindBy( customerId ); + Assert.AreEqual( 1, ListFactory.From( customer.RegisteredBoats( ) ).Count ); + Assert.IsTrue( ListFactory.From( customer.RegisteredBoats( ) ).Contains( boat ) ); + } + } + + [Test] + public void Should_leverage_mapper_to_load_customer_leases() { + long customerId = 32; + IList< ISlipLease > leases = new List< ISlipLease >( ); + ISlipLease lease = _mockery.DynamicMock< ISlipLease >( ); + leases.Add( lease ); + + using ( _mockery.Record( ) ) { + Expect + .Call( _leaseDataMapper.AllLeasesFor( customerId ) ) + .Return( leases ); + } + + using ( _mockery.Playback( ) ) { + ICustomer customer = CreateSUT( ).FindBy( customerId ); + Assert.AreEqual( 1, ListFactory.From( customer.Leases( ) ).Count ); + Assert.IsTrue( ListFactory.From( customer.Leases( ) ).Contains( lease ) ); + } + } + + [Test] + public void Should_leverage_mapper_to_load_customer_registration() { + long customerId = 59; + + IRegistration registration = _mockery.DynamicMock< IRegistration >( ); + + using ( _mockery.Record( ) ) { + Expect.Call( _registrationMapper.For( customerId ) ).Return( registration ); + } + + using ( _mockery.Playback( ) ) { + ICustomer customer = CreateSUT( ).FindBy( customerId ); + Assert.AreEqual( registration, customer.Registration( ) ); + } + } + } +} \ No newline at end of file diff --git a/slips/src/test/Marina.Test/Unit/DataAccess/Repositories/CustomerRepositoryTest.cs b/slips/src/test/Marina.Test/Unit/DataAccess/Repositories/CustomerRepositoryTest.cs new file mode 100644 index 0000000..afc21fc --- /dev/null +++ b/slips/src/test/Marina.Test/Unit/DataAccess/Repositories/CustomerRepositoryTest.cs @@ -0,0 +1,142 @@ +using Marina.DataAccess; +using Marina.DataAccess.DataMappers; +using Marina.DataAccess.Repositories; +using Marina.Domain.Interfaces; +using Marina.Domain.Repositories; +using MbUnit.Framework; +using Rhino.Mocks; + +namespace Marina.Test.Unit.DataAccess.Repositories { + [TestFixture] + public class CustomerRepositoryTest { + private MockRepository _mockery; + private IIdentityMap< ICustomer > _mockIdentityMap; + private ICustomerDataMapper _mockMapper; + + [SetUp] + public void Setup() { + _mockery = new MockRepository( ); + _mockIdentityMap = _mockery.DynamicMock< IIdentityMap< ICustomer > >( ); + _mockMapper = _mockery.DynamicMock< ICustomerDataMapper >( ); + } + + public ICustomerRepository CreateSUT() { + return CreateSUT( _mockIdentityMap, _mockMapper ); + } + + private ICustomerRepository CreateSUT( IIdentityMap< ICustomer > identityMap, ICustomerDataMapper mapper ) { + return new CustomerRepository( identityMap, mapper ); + } + + [Test] + public void Should_check_identity_map_to_see_if_customer_is_loaded() { + ICustomer customer = _mockery.DynamicMock< ICustomer >( ); + long customerId = 23455; + + using ( _mockery.Record( ) ) { + Expect.Call( _mockIdentityMap.ContainsObjectWithIdOf( customerId ) ).Return( true ); + Expect.Call( _mockIdentityMap.FindObjectWithIdOf( customerId ) ).Return( customer ); + } + + using ( _mockery.Playback( ) ) { + Assert.AreEqual( customer, CreateSUT( ).FindBy( customerId ) ); + } + } + + [Test] + public void Should_leverage_mapper_to_load_customer_if_not_in_identity_map() { + ICustomer customer = _mockery.DynamicMock< ICustomer >( ); + long customerId = 23455; + + using ( _mockery.Record( ) ) { + SetupResult.For( _mockIdentityMap.ContainsObjectWithIdOf( customerId ) ).Return( false ); + Expect.Call( _mockMapper.FindBy( customerId ) ).Return( customer ); + } + + using ( _mockery.Playback( ) ) { + Assert.AreEqual( customer, CreateSUT( ).FindBy( customerId ) ); + } + } + + [Test] + public void Should_add_customer_to_identity_map_after_retrieving_from_mapper() { + ICustomer customer = _mockery.DynamicMock< ICustomer >( ); + long customerId = 23455; + + using ( _mockery.Record( ) ) { + SetupResult.For( _mockIdentityMap.ContainsObjectWithIdOf( customerId ) ).Return( false ); + SetupResult.For( _mockMapper.FindBy( customerId ) ).Return( customer ); + _mockIdentityMap.Add( customer ); + } + + using ( _mockery.Playback( ) ) { + Assert.AreEqual( customer, CreateSUT( ).FindBy( customerId ) ); + } + } + + [Test] + public void Should_create_a_new_customer() { + using ( _mockery.Record( ) ) {} + + using ( _mockery.Playback( ) ) { + ICustomer newCustomer = CreateSUT( ).NewCustomer( ); + Assert.AreEqual( -1, newCustomer.ID( ) ); + } + } + + [Test] + public void Should_leverage_mapper_to_insert_new_customer() { + ICustomer customer = _mockery.DynamicMock< ICustomer >( ); + long customerId = 34; + + using ( _mockery.Record( ) ) { + SetupResult.For( customer.ID( ) ).Return( customerId ); + SetupResult.For( _mockIdentityMap.ContainsObjectWithIdOf( customerId ) ).Return( false ); + + _mockMapper.Insert( customer ); + } + + using ( _mockery.Playback( ) ) { + CreateSUT( ).Save( customer ); + } + } + + [Test] + public void Should_add_new_customer_to_identity_map_after_insert() { + ICustomer customer = _mockery.DynamicMock< ICustomer >( ); + long customerId = 34; + + using ( _mockery.Record( ) ) { + SetupResult.For( customer.ID( ) ).Return( customerId ); + SetupResult.For( _mockIdentityMap.ContainsObjectWithIdOf( customerId ) ).Return( false ); + using ( _mockery.Ordered( ) ) { + _mockMapper.Insert( customer ); + _mockIdentityMap.Add( customer ); + } + } + + using ( _mockery.Playback( ) ) { + CreateSUT( ).Save( customer ); + } + } + + [Test] + public void Should_leverage_mapper_to_update_customer() { + ICustomer customer = _mockery.DynamicMock< ICustomer >( ); + IIdentityMap< ICustomer > identityMap = _mockery.CreateMock< IIdentityMap< ICustomer > >( ); + ICustomerDataMapper dataMapper = _mockery.CreateMock< ICustomerDataMapper >( ); + long customerId = 46; + + using ( _mockery.Record( ) ) { + SetupResult.For( customer.ID( ) ).Return( customerId ); + SetupResult.For( identityMap.ContainsObjectWithIdOf( customerId ) ).Return( true ); + + dataMapper.Update( customer ); + } + + using ( _mockery.Playback( ) ) { + CreateSUT( identityMap, dataMapper ).Save( customer ); + } + } + } +} \ No newline at end of file diff --git a/slips/src/test/Marina.Test/Unit/DataAccess/Repositories/DockRepositoryTest.cs b/slips/src/test/Marina.Test/Unit/DataAccess/Repositories/DockRepositoryTest.cs new file mode 100644 index 0000000..5d17679 --- /dev/null +++ b/slips/src/test/Marina.Test/Unit/DataAccess/Repositories/DockRepositoryTest.cs @@ -0,0 +1,38 @@ +using Marina.DataAccess.DataMappers; +using Marina.DataAccess.Repositories; +using Marina.Domain.Interfaces; +using Marina.Domain.Repositories; +using MbUnit.Framework; +using Rhino.Mocks; + +namespace Marina.Test.Unit.DataAccess.Repositories { + [TestFixture] + public class DockRepositoryTest { + private MockRepository _mockery; + private IDockDataMapper mockMapper; + + [SetUp] + public void Setup() { + _mockery = new MockRepository( ); + mockMapper = _mockery.DynamicMock< IDockDataMapper >( ); + } + + public IDockRepository CreateSUT() { + return new DockRepository( mockMapper ); + } + + [Test] + public void Should_leverage_mapper_to_retrieve_dock_by_id() { + IDock dock = _mockery.DynamicMock< IDock >( ); + long dockId = 2; + + using ( _mockery.Record( ) ) { + Expect.Call( mockMapper.FindBy( dockId ) ).Return( dock ); + } + + using ( _mockery.Playback( ) ) { + Assert.AreEqual( dock, CreateSUT( ).FindBy( dockId ) ); + } + } + } +} \ No newline at end of file diff --git a/slips/src/test/Marina.Test/Unit/DataAccess/Repositories/IdentityMapTest.cs b/slips/src/test/Marina.Test/Unit/DataAccess/Repositories/IdentityMapTest.cs new file mode 100644 index 0000000..9ff01c8 --- /dev/null +++ b/slips/src/test/Marina.Test/Unit/DataAccess/Repositories/IdentityMapTest.cs @@ -0,0 +1,71 @@ +using Marina.DataAccess; +using Marina.DataAccess.Exceptions; +using Marina.Domain; +using Marina.Domain.Interfaces; +using MbUnit.Framework; + +namespace Marina.Test.Unit.DataAccess.Repositories { + [TestFixture] + public class IdentityMapTest { + public IIdentityMap< IDomainObject > CreateSUT() { + return new IdentityMap< IDomainObject >( ); + } + + // should not be able to add an object with an id of -1 + + [Test] + public void Should_be_able_to_add_a_new_domain_object_to_the_identitiy_map() { + IDomainObject objectThatHasBeenAddedToMap = new DomainObject( 1 ); + IDomainObject objectThatHasNotBeenAddedToMap = new DomainObject( 2 ); + + IIdentityMap< IDomainObject > map = CreateSUT( ); + map.Add( objectThatHasBeenAddedToMap ); + + Assert.IsTrue( map.ContainsObjectWithIdOf( objectThatHasBeenAddedToMap.ID( ) ) ); + Assert.IsFalse( map.ContainsObjectWithIdOf( objectThatHasNotBeenAddedToMap.ID( ) ) ); + } + + [Test] + public void Should_return_true_if_searching_for_a_() { + IIdentityMap< IDomainObject > map = CreateSUT( ); + + int id = 1; + map.Add( new DomainObject( id ) ); + + Assert.IsTrue( map.ContainsObjectWithIdOf( id ) ); + Assert.IsFalse( map.ContainsObjectWithIdOf( 2 ) ); + } + + [Test] + public void Should_be_able_to_retrieve_an_object_that_has_been_added_to_the_map() { + IIdentityMap< IDomainObject > map = CreateSUT( ); + IDomainObject objectAddedToMap = new DomainObject( 1 ); + map.Add( objectAddedToMap ); + + Assert.AreEqual( objectAddedToMap, map.FindObjectWithIdOf( 1 ) ); + } + + [Test] + public void Should_return_null_if_the_object_is_not_in_the_map() { + Assert.IsNull( CreateSUT( ).FindObjectWithIdOf( 1 ) ); + } + + [Test] + [ExpectedException( typeof( ObjectAlreadyAddedToIdentityMapException ) )] + public void Should_not_be_able_to_add_an_object_that_has_already_been_added() { + IIdentityMap< IDomainObject > map = CreateSUT( ); + IDomainObject addedObject = new DomainObject( 1 ); + map.Add( addedObject ); + map.Add( addedObject ); + } + + [Test] + [ExpectedException( typeof( ObjectAlreadyAddedToIdentityMapException ) )] + public void Should_not_be_able_to_add_an_object_with_the_same_id_as_one_that_was_already_added() { + IIdentityMap< IDomainObject > map = CreateSUT( ); + int id = 1; + map.Add( new DomainObject( id ) ); + map.Add( new DomainObject( id ) ); + } + } +} \ No newline at end of file diff --git a/slips/src/test/Marina.Test/Unit/DataAccess/Repositories/SlipRepositoryTest.cs b/slips/src/test/Marina.Test/Unit/DataAccess/Repositories/SlipRepositoryTest.cs new file mode 100644 index 0000000..31b5d7a --- /dev/null +++ b/slips/src/test/Marina.Test/Unit/DataAccess/Repositories/SlipRepositoryTest.cs @@ -0,0 +1,50 @@ +using System.Collections.Generic; +using Marina.DataAccess.DataMappers; +using Marina.DataAccess.Repositories; +using Marina.Domain.Interfaces; +using Marina.Domain.Repositories; +using Marina.Infrastructure; +using MbUnit.Framework; +using Rhino.Mocks; + +namespace Marina.Test.Unit.DataAccess.Repositories { + [TestFixture] + public class SlipRepositoryTest { + private MockRepository _mockery; + private ISlipDataMapper _mockMapper; + + [SetUp] + public void Setup() { + _mockery = new MockRepository( ); + _mockMapper = _mockery.DynamicMock< ISlipDataMapper >( ); + } + + public ISlipsRepository CreateSUT() { + return new SlipsRepository( _mockMapper ); + } + + [Test] + public void Should_leverage_mapper_to_convert_from_table_to_a_domain_object() { + ISlip unleasedSlip = _mockery.DynamicMock< ISlip >( ); + ISlip leasedSlip = _mockery.DynamicMock< ISlip >( ); + + IList< ISlip > slips = new List< ISlip >( ); + slips.Add( unleasedSlip ); + slips.Add( leasedSlip ); + + using ( _mockery.Record( ) ) { + SetupResult.For( unleasedSlip.IsLeased( ) ).Return( false ); + SetupResult.For( leasedSlip.IsLeased( ) ).Return( true ); + + Expect.Call( _mockMapper.AllSlips( ) ).Return( new RichEnumerable< ISlip >( slips ) ); + } + + using ( _mockery.Playback( ) ) { + IRichList< ISlip > foundSlips = ListFactory.From( CreateSUT( ).AllAvailableSlips( ) ); + + Assert.IsTrue( foundSlips.Contains( unleasedSlip ) ); + Assert.IsFalse( foundSlips.Contains( leasedSlip ) ); + } + } + } +} \ No newline at end of file diff --git a/slips/src/test/Marina.Test/Unit/Domain/CustomerRegistrationTest.cs b/slips/src/test/Marina.Test/Unit/Domain/CustomerRegistrationTest.cs new file mode 100644 index 0000000..dce27ad --- /dev/null +++ b/slips/src/test/Marina.Test/Unit/Domain/CustomerRegistrationTest.cs @@ -0,0 +1,50 @@ +using Marina.Domain; +using Marina.Domain.Interfaces; +using Marina.Infrastructure; +using MbUnit.Framework; + +namespace Marina.Test.Unit.Domain { + [TestFixture] + public class CustomerRegistrationTest { + public IRegistration CreateSUT( string userName, string password ) { + return new CustomerRegistration( userName, password, "mo", "khan", "4036813389", "calgary" ); + } + + [Test] + public void Should_not_allow_blank_password() { + string blankPassword = string.Empty; + IRegistration registration = CreateSUT( "username", blankPassword ); + IRichList< IBrokenRule > brokenRules = ListFactory.From( registration.BrokenRules( ) ); + + Assert.IsFalse( registration.IsValid( ) ); + Assert.AreEqual( "Password cannot be blank", brokenRules[ 0 ].Message( ) ); + } + + [Test] + public void Should_not_allow_blank_username() { + string blankUserName = string.Empty; + IRegistration registration = CreateSUT( blankUserName, "password" ); + IRichList< IBrokenRule > brokenRules = ListFactory.From( registration.BrokenRules( ) ); + + Assert.IsFalse( registration.IsValid( ) ); + Assert.AreEqual( "Username cannot be blank", brokenRules[ 0 ].Message( ) ); + } + + [Test] + public void Should_be_valid() { + Assert.IsTrue( CreateSUT( "username", "password" ).IsValid( ) ); + } + + [Test] + public void Shoud_return_no_broken_rules() { + IRegistration registration = CreateSUT( "userName", "PASSWORD" ); + IRichList< IBrokenRule > brokenRules = ListFactory.From( registration.BrokenRules( ) ); + Assert.AreEqual( 0, brokenRules.Count ); + } + + [Test] + public void Should_be_equal() { + Assert.AreEqual( CreateSUT( "mokhan", "password" ), CreateSUT( "mokhan", "password" ) ); + } + } +} \ No newline at end of file diff --git a/slips/src/test/Marina.Test/Unit/Domain/CustomerTest.cs b/slips/src/test/Marina.Test/Unit/Domain/CustomerTest.cs new file mode 100644 index 0000000..604b049 --- /dev/null +++ b/slips/src/test/Marina.Test/Unit/Domain/CustomerTest.cs @@ -0,0 +1,118 @@ +using System; +using Marina.Domain; +using Marina.Domain.Exceptions; +using Marina.Domain.Interfaces; +using Marina.Infrastructure; +using Marina.Test.Utility; +using MbUnit.Framework; +using Rhino.Mocks; + +namespace Marina.Test.Unit.Domain { + [TestFixture] + public class CustomerTest { + private MockRepository _mockery; + + [SetUp] + public void Setup() { + _mockery = new MockRepository( ); + } + + public ICustomer CreateSUT() { + return new Customer( ); + } + + [Test] + public void Should_be_able_to_register_a_new_boat() { + ICustomer customer = CreateSUT( ); + + Assert.AreEqual( 0, ListFactory.From( customer.RegisteredBoats( ) ).Count ); + customer.RegisterBoat( ObjectMother.Boat( ) ); + Assert.AreEqual( 1, ListFactory.From( customer.RegisteredBoats( ) ).Count ); + } + + [Test] + public void Should_not_be_able_to_register_an_already_registered_boat() { + ICustomer customer = CreateSUT( ); + IBoat boat = ObjectMother.Boat( ); + customer.RegisterBoat( boat ); + customer.RegisterBoat( boat ); + + Assert.AreEqual( 1, ListFactory.From( customer.RegisteredBoats( ) ).Count ); + } + + [Test] + public void Should_be_able_to_lease_a_slip() { + ICustomer customer = CreateSUT( ); + ISlip slip = ObjectMother.Slip( ); + ILeaseDuration duration = LeaseDurations.Monthly; + + customer.Lease( slip, duration ); + + Assert.AreEqual( 1, ListFactory.From( customer.Leases( ) ).Count ); + } + + [Test] + [ExpectedException( typeof( SlipIsAlreadyLeasedException ) )] + public void Should_not_be_able_to_lease_a_slip_that_is_already_leased() { + ISlip slip = _mockery.DynamicMock< ISlip >( ); + + using ( _mockery.Record( ) ) { + SetupResult.For( slip.IsLeased( ) ).Return( true ); + } + + using ( _mockery.Playback( ) ) { + ICustomer customer = CreateSUT( ); + customer.Lease( slip, LeaseDurations.Yearly ); + Assert.AreEqual( 0, ListFactory.From( customer.Leases( ) ).Count ); + } + } + + [Test] + public void Should_be_able_to_register_an_unregistered_boat() { + string registrationNumber = "435535"; + string manufacturer = "YAMAHA"; + DateTime yearOfModel = new DateTime( 1990, 01, 01 ); + long lengthInFeet = 100; + + ICustomer customer = CreateSUT( ); + customer.RegisterBoat( registrationNumber, manufacturer, yearOfModel, lengthInFeet ); + + IRichList< IBoat > boats = ListFactory.From( customer.RegisteredBoats( ) ); + + Assert.AreEqual( 1, boats.Count ); + Assert.AreEqual( registrationNumber, boats[ 0 ].RegistrationNumber( ) ); + Assert.AreEqual( manufacturer, boats[ 0 ].Manufacturer( ) ); + Assert.AreEqual( yearOfModel, boats[ 0 ].YearOfModel( ) ); + Assert.AreEqual( lengthInFeet, boats[ 0 ].LengthInFeet( ) ); + } + + [Test] + public void Should_be_able_to_register_an_account() { + ICustomer customer = CreateSUT( ); + customer.RegisterAccount( "username", "password", "mo", "khan", "4036813389", "calgary" ); + IRegistration registration = customer.Registration( ); + + Assert.AreEqual( "username", registration.Username( ) ); + Assert.AreEqual( "password", registration.Password( ) ); + Assert.AreEqual( "mo", registration.FirstName( ) ); + Assert.AreEqual( "khan", registration.LastName( ) ); + Assert.AreEqual( "4036813389", registration.PhoneNumber( ) ); + Assert.AreEqual( "calgary", registration.City( ) ); + } + + [Test] + public void should_have_no_registration_information() { + IRegistration registration = CreateSUT( ).Registration( ); + Assert.AreEqual( "", registration.Username( ) ); + Assert.AreEqual( "", registration.Password( ) ); + } + + [Test] + public void Should_be_able_to_update_the_registration_information() { + IRegistration registration = _mockery.DynamicMock< IRegistration >( ); + ICustomer customer = CreateSUT( ); + customer.UpdateRegistrationTo( registration ); + Assert.AreEqual( registration, customer.Registration( ) ); + } + } +} \ No newline at end of file diff --git a/slips/src/test/Marina.Test/Unit/Domain/DockTest.cs b/slips/src/test/Marina.Test/Unit/Domain/DockTest.cs new file mode 100644 index 0000000..7d4405a --- /dev/null +++ b/slips/src/test/Marina.Test/Unit/Domain/DockTest.cs @@ -0,0 +1,24 @@ +using Marina.Domain; +using Marina.Domain.Interfaces; +using Marina.Test.Utility; +using MbUnit.Framework; + +namespace Marina.Test.Unit.Domain { + [TestFixture] + public class DockTest { + private static IDock CreateSUT( params IUtility[] utilities ) { + return new Dock( 1, "dock a", ObjectMother.Location( ), Utilities.For( utilities ) ); + } + + [Test] + public void Should_be_able_to_tell_if_a_utility_is_enabled_at_the_dock() { + IDock dock = CreateSUT( Utilities.Water ); + Assert.IsTrue( dock.IsUtilityEnabled( Utilities.Water ) ); + Assert.IsFalse( dock.IsUtilityEnabled( Utilities.Electrical ) ); + + dock = CreateSUT( Utilities.Water, Utilities.Electrical ); + Assert.IsTrue( dock.IsUtilityEnabled( Utilities.Water ) ); + Assert.IsTrue( dock.IsUtilityEnabled( Utilities.Electrical ) ); + } + } +} \ No newline at end of file diff --git a/slips/src/test/Marina.Test/Unit/Domain/LeaseDurationTest.cs b/slips/src/test/Marina.Test/Unit/Domain/LeaseDurationTest.cs new file mode 100644 index 0000000..dab44f2 --- /dev/null +++ b/slips/src/test/Marina.Test/Unit/Domain/LeaseDurationTest.cs @@ -0,0 +1,45 @@ +using System; +using Marina.Domain; +using Marina.Domain.Interfaces; +using MbUnit.Framework; + +namespace Marina.Test.Unit.Domain { + [TestFixture] + public class LeaseDurationTest { + [Test] + public void Should_return_daily_lease_duration() { + DateTime yesterday = DateTime.Now.AddDays( -1 ); + DateTime today = DateTime.Now; + + ILeaseDuration duration = LeaseDurations.FindFor( yesterday, today ); + Assert.AreEqual( LeaseDurations.Daily, duration ); + } + + [Test] + public void Should_return_weekly_lease_duration() { + DateTime aWeekAgo = DateTime.Now.AddDays( -7 ).Date; + DateTime today = DateTime.Now.Date; + + ILeaseDuration duration = LeaseDurations.FindFor( aWeekAgo, today ); + Assert.AreEqual( LeaseDurations.Weekly, duration ); + } + + [Test] + public void Should_return_monthly_lease_duration() { + DateTime aMonthAgo = DateTime.Now.AddDays( -30 ); + DateTime today = DateTime.Now; + + ILeaseDuration duration = LeaseDurations.FindFor( aMonthAgo, today ); + Assert.AreEqual( LeaseDurations.Monthly, duration ); + } + + [Test] + public void Should_return_yearly_lease_duration() { + DateTime aYearAgo = DateTime.Now.AddDays( -365 ); + DateTime today = DateTime.Now; + + ILeaseDuration duration = LeaseDurations.FindFor( aYearAgo, today ); + Assert.AreEqual( LeaseDurations.Yearly, duration ); + } + } +} \ No newline at end of file diff --git a/slips/src/test/Marina.Test/Unit/Domain/SlipTest.cs b/slips/src/test/Marina.Test/Unit/Domain/SlipTest.cs new file mode 100644 index 0000000..300a441 --- /dev/null +++ b/slips/src/test/Marina.Test/Unit/Domain/SlipTest.cs @@ -0,0 +1,78 @@ +using System; +using Marina.Domain; +using Marina.Domain.Exceptions; +using Marina.Domain.Interfaces; +using Marina.Test.Utility; +using MbUnit.Framework; + +namespace Marina.Test.Unit.Domain { + [TestFixture] + public class SlipTest { + public ISlip CreateSUT() { + return new Slip( -1, ObjectMother.Dock( ), 100, 100, false ); + } + + [Test] + public void Should_not_be_leased_to_anyone() { + Assert.IsFalse( CreateSUT( ).IsLeased( ) ); + } + + //[Test] + //public void Should_be_able_to_lease_to_a_customer() + //{ + // ICustomer customer = ObjectMother.Customer(); + // ISlip slip = CreateSUT(); + // ILeaseDuration durationOfLease = LeaseDurations.Daily; + + // ISlipLease lease = slip.LeaseTo(customer, durationOfLease); + + // Assert.AreEqual(customer, lease.Owner()); + // Assert.AreEqual(slip, lease.Slip()); + // Assert.AreEqual(durationOfLease, lease.Duration()); + // Assert.AreEqual(DateTime.Now.Date, lease.StartDate()); + //} + + [Test] + public void Lease_should_expire_at_11_am_the_following_day() { + DateTime elevenAmTomorrow = DateTime.Now.AddDays( 1 ).Date.AddHours( 11 ); + ISlipLease lease = CreateSUT( ).LeaseTo( ObjectMother.Customer( ), LeaseDurations.Daily ); + Assert.AreEqual( elevenAmTomorrow, lease.ExpiryDate( ) ); + } + + [Test] + public void Lease_should_expire_in_seven_days_on_the_eleventh_hour() { + DateTime oneWeekFromToday = DateTime.Now.AddDays( 7 ).Date.AddHours( 11 ); + ISlipLease lease = CreateSUT( ).LeaseTo( ObjectMother.Customer( ), LeaseDurations.Weekly ); + Assert.AreEqual( oneWeekFromToday, lease.ExpiryDate( ) ); + } + + [Test] + public void Lease_should_expire_in_thirty_days_on_the_eleventh_hour() { + DateTime oneMonthFromToday = DateTime.Now.AddDays( 30 ).Date.AddHours( 11 ); + ISlipLease lease = CreateSUT( ).LeaseTo( ObjectMother.Customer( ), LeaseDurations.Monthly ); + Assert.AreEqual( oneMonthFromToday, lease.ExpiryDate( ) ); + } + + [Test] + public void Lease_should_expire_in_365_days_on_the_eleventh_hour() { + DateTime oneYearFromToday = DateTime.Now.AddDays( 365 ).Date.AddHours( 11 ); + ISlipLease lease = CreateSUT( ).LeaseTo( ObjectMother.Customer( ), LeaseDurations.Yearly ); + Assert.AreEqual( oneYearFromToday, lease.ExpiryDate( ) ); + } + + [Test] + public void Should_be_leased_to_an_owner() { + ISlip slip = CreateSUT( ); + slip.LeaseTo( ObjectMother.Customer( ), LeaseDurations.Yearly ); + Assert.IsTrue( slip.IsLeased( ), "Should be leased to an owner" ); + } + + [Test] + [ExpectedException( typeof( SlipIsAlreadyLeasedException ) )] + public void Should_return_current_lease_if_it_is_already_leased_to_a_customer() { + ISlip slip = CreateSUT( ); + slip.LeaseTo( ObjectMother.Customer( ), LeaseDurations.Yearly ); + slip.LeaseTo( ObjectMother.Customer( ), LeaseDurations.Weekly ); + } + } +} \ No newline at end of file diff --git a/slips/src/test/Marina.Test/Unit/Domain/UtilitiesTest.cs b/slips/src/test/Marina.Test/Unit/Domain/UtilitiesTest.cs new file mode 100644 index 0000000..c01d5d4 --- /dev/null +++ b/slips/src/test/Marina.Test/Unit/Domain/UtilitiesTest.cs @@ -0,0 +1,36 @@ +using Marina.Domain; +using Marina.Domain.Interfaces; +using MbUnit.Framework; + +namespace Marina.Test.Unit.Domain { + [TestFixture] + public class UtilitiesTest { + [Test] + public void Should_be_equal_to_a_single_utility() { + IUtility utility = Utilities.For( Utilities.Electrical ); + Assert.IsTrue( utility.IsEnabled( Utilities.Electrical ) ); + } + + [Test] + public void Should_be_equal_to_two_utilities() { + IUtility utility = Utilities.For( Utilities.Electrical, Utilities.Water ); + + Assert.IsTrue( utility.IsEnabled( Utilities.Electrical ) ); + Assert.IsTrue( utility.IsEnabled( Utilities.Water ) ); + } + + [Test] + public void Should_not_be_equal_to_either_utilities() { + IUtility utility = Utilities.For( null ); + + Assert.IsFalse( utility.IsEnabled( Utilities.Electrical ) ); + Assert.IsFalse( utility.IsEnabled( Utilities.Water ) ); + } + + [Test] + public void Should_have_water_enabled() { + IUtility utility = Utilities.For( null, Utilities.Water ); + Assert.IsTrue( utility.IsEnabled( Utilities.Water ) ); + } + } +} \ No newline at end of file diff --git a/slips/src/test/Marina.Test/Unit/Infrastructure/Logging/Interfaces/LogTest.cs b/slips/src/test/Marina.Test/Unit/Infrastructure/Logging/Interfaces/LogTest.cs new file mode 100644 index 0000000..504d598 --- /dev/null +++ b/slips/src/test/Marina.Test/Unit/Infrastructure/Logging/Interfaces/LogTest.cs @@ -0,0 +1,36 @@ +using Marina.Infrastructure.Container; +using Marina.Infrastructure.Logging.Interfaces; +using MbUnit.Framework; +using Rhino.Mocks; + +namespace Marina.Test.Unit.Infrastructure.Logging.Interfaces { + [TestFixture] + public class LogTest { + private MockRepository mockery; + + [SetUp] + public void SetUp( ) { + mockery = new MockRepository( ); + } + + [Test] + public void Should_leverage_factory_to_return_a_logger_to_the_client( ) { + ILog mockLog = mockery.DynamicMock< ILog >( ); + ILogFactory mockLogFactory = mockery.DynamicMock< ILogFactory >( ); + + IDependencyContainer mockContainer = mockery.DynamicMock< IDependencyContainer >( ); + + using ( mockery.Record( ) ) { + Expect.Call( mockContainer.GetMeAnImplementationOfAn< ILogFactory >( ) ).Return( mockLogFactory ); + Expect.Call( mockLogFactory.CreateFor( typeof( LogTest ) ) ).Return( mockLog ); + } + + using ( mockery.Playback( ) ) { + Resolve.InitializeWith( mockContainer ); + ILog log = Log.For( this ); + Assert.AreEqual( mockLog, log ); + Resolve.InitializeWith( null ); + } + } + } +} \ No newline at end of file diff --git a/slips/src/test/Marina.Test/Unit/Infrastructure/Logging/TextWriterLogging/TextWriterLogFactoryTest.cs b/slips/src/test/Marina.Test/Unit/Infrastructure/Logging/TextWriterLogging/TextWriterLogFactoryTest.cs new file mode 100644 index 0000000..7827274 --- /dev/null +++ b/slips/src/test/Marina.Test/Unit/Infrastructure/Logging/TextWriterLogging/TextWriterLogFactoryTest.cs @@ -0,0 +1,19 @@ +using Marina.Infrastructure.Logging.Interfaces; +using Marina.Infrastructure.Logging.TextWriterLogging; +using MbUnit.Framework; + +namespace Marina.Test.Unit.Infrastructure.TextWriterLogging { + [TestFixture] + public class TextWriterLogFactoryTest { + [Test] + public void Should_create_a_text_writer_log( ) { + ILog log = CreateSUT( ).CreateFor( this.GetType( ) ); + Assert.IsNotNull( log ); + Assert.IsInstanceOfType( typeof( TextWriterLog ), log ); + } + + private ILogFactory CreateSUT( ) { + return new TextWriterLogFactory( ); + } + } +} \ No newline at end of file diff --git a/slips/src/test/Marina.Test/Unit/Infrastructure/Logging/TextWriterLogging/TextWriterLogTest.cs b/slips/src/test/Marina.Test/Unit/Infrastructure/Logging/TextWriterLogging/TextWriterLogTest.cs new file mode 100644 index 0000000..526590c --- /dev/null +++ b/slips/src/test/Marina.Test/Unit/Infrastructure/Logging/TextWriterLogging/TextWriterLogTest.cs @@ -0,0 +1,26 @@ +using System.IO; +using System.Text; +using Marina.Infrastructure.Logging.Interfaces; +using Marina.Infrastructure.Logging.TextWriterLogging; +using MbUnit.Framework; + +namespace Marina.Test.Unit.Infrastructure.TextWriterLogging { + [TestFixture] + public class TextWriterLogTest { + [Test] + public void Should_log_message_to_backing_store( ) { + string expectedMessage = "Message"; + + StringWriter writer = new StringWriter( new StringBuilder( ) ); + + ILog consoleLogger = CreateSUT( writer ); + consoleLogger.Informational( expectedMessage ); + + Assert.AreEqual( expectedMessage, writer.ToString( ).Trim( ) ); + } + + private ILog CreateSUT( TextWriter writer ) { + return new TextWriterLog( writer ); + } + } +} \ No newline at end of file diff --git a/slips/src/test/Marina.Test/Unit/Infrastructure/TransformTest.cs b/slips/src/test/Marina.Test/Unit/Infrastructure/TransformTest.cs new file mode 100644 index 0000000..49f67ac --- /dev/null +++ b/slips/src/test/Marina.Test/Unit/Infrastructure/TransformTest.cs @@ -0,0 +1,37 @@ +using System; +using System.Data; +using Marina.Infrastructure; +using MbUnit.Framework; + +namespace Marina.Test.Unit.Infrastructure { + [TestFixture] + public class TransformerTest { + [Test] + public void Should_be_able_to_cast_to_the_actual_type_of_the_underlying_object( ) { + object item = new Item( ); + + Item result = CreateSUT( item ).To< Item >( ); + Assert.AreEqual( item, result ); + } + + [ExpectedException( typeof( NullReferenceException ) )] + [Test] + public void Should_not_be_able_to_cast_from_null_to_a_type( ) { + CreateSUT( null ).To< Item >( ); + } + + [ExpectedException( typeof( InvalidCastException ) )] + [Test] + public void Should_not_be_able_to_cast_from_one_instance_to_a_non_assignable_type( ) { + Item item = new Item( ); + + CreateSUT( item ).To< IDbConnection >( ); + } + + private ITransformer CreateSUT( object item ) { + return new Transformer( item ); + } + + private class Item {} + } +} \ No newline at end of file diff --git a/slips/src/test/Marina.Test/Unit/Presentation/AvailableSlipsPresenterTest.cs b/slips/src/test/Marina.Test/Unit/Presentation/AvailableSlipsPresenterTest.cs new file mode 100644 index 0000000..5fa950a --- /dev/null +++ b/slips/src/test/Marina.Test/Unit/Presentation/AvailableSlipsPresenterTest.cs @@ -0,0 +1,51 @@ +using System.Collections.Generic; +using Marina.Presentation.DTO; +using Marina.Presentation.Presenters; +using Marina.Presentation.Views; +using Marina.Task; +using MbUnit.Framework; +using Rhino.Mocks; + +namespace Marina.Test.Unit.Presentation { + [TestFixture] + public class AvailableSlipsPresenterTest { + private MockRepository mockery; + private ICatalogTasks mockTask; + private IAvailableSlipsView mockView; + + [SetUp] + public void SetUp( ) { + mockery = new MockRepository( ); + mockTask = mockery.DynamicMock< ICatalogTasks >( ); + mockView = mockery.DynamicMock< IAvailableSlipsView >( ); + } + + [Test] + public void Should_leverage_task_to_retrieve_all_available_slips_on_initialize( ) { + using ( mockery.Record( ) ) { + Expect.Call( mockTask.GetAllAvailableSlips( ) ).Return( null ); + } + + using ( mockery.Playback( ) ) { + CreateSUT( ).Initialize( ); + } + } + + [Test] + public void Should_display_the_available_slips( ) { + IEnumerable< SlipDisplayDTO > availableSlips = new List< SlipDisplayDTO >( ); + using ( mockery.Record( ) ) { + SetupResult.For( mockTask.GetAllAvailableSlips( ) ).Return( availableSlips ); + mockView.Display( availableSlips ); + } + + using ( mockery.Playback( ) ) { + CreateSUT( ).Initialize( ); + } + } + + private IAvailableSlipsPresenter CreateSUT( ) { + return new AvailableSlipsPresenter( mockView, mockTask ); + } + } +} \ No newline at end of file diff --git a/slips/src/test/Marina.Test/Unit/Presentation/CurrentLeasesPresenterTest.cs b/slips/src/test/Marina.Test/Unit/Presentation/CurrentLeasesPresenterTest.cs new file mode 100644 index 0000000..a9f2cb1 --- /dev/null +++ b/slips/src/test/Marina.Test/Unit/Presentation/CurrentLeasesPresenterTest.cs @@ -0,0 +1,63 @@ +using System.Collections.Generic; +using Marina.Presentation; +using Marina.Presentation.DTO; +using Marina.Presentation.Presenters; +using Marina.Presentation.Views; +using Marina.Task; +using Marina.Web; +using MbUnit.Framework; +using Rhino.Mocks; + +namespace Marina.Test.Unit.Presentation { + [TestFixture] + public class CurrentLeasesPresenterTest { + private MockRepository _mockery; + private ILeaseTasks task; + private IHttpRequest mockRequest; + private ICurrentLeasesView mockView; + + [SetUp] + public void Setup() { + _mockery = new MockRepository( ); + task = _mockery.DynamicMock< ILeaseTasks >( ); + mockRequest = _mockery.DynamicMock< IHttpRequest >( ); + mockView = _mockery.DynamicMock< ICurrentLeasesView >( ); + } + + public ICurrentLeasesPresenter CreateSUT() { + return new CurrentLeasesPresenter( mockView, mockRequest, task ); + } + + [Test] + public void Should_leverage_task_to_retrieve_all_leases_for_customer_id() { + long customerId = 32; + IList< DisplayLeaseDTO > dtos = new List< DisplayLeaseDTO >( ); + + using ( _mockery.Record( ) ) { + SetupResult.For( mockRequest.ParsePayloadFor( PayloadKeys.CustomerId ) ).Return( customerId ); + Expect.Call( task.FindAllLeasesFor( customerId ) ).Return( dtos ); + } + + using ( _mockery.Playback( ) ) { + CreateSUT( ).Initialize( ); + } + } + + [Test] + public void Should_display_the_found_leases_on_the_view() { + IList< DisplayLeaseDTO > dtos = new List< DisplayLeaseDTO >( ); + using ( _mockery.Record( ) ) { + SetupResult + .For( task.FindAllLeasesFor( 0 ) ) + .IgnoreArguments( ) + .Return( dtos ); + + mockView.Display( dtos ); + } + + using ( _mockery.Playback( ) ) { + CreateSUT( ).Initialize( ); + } + } + } +} \ No newline at end of file diff --git a/slips/src/test/Marina.Test/Unit/Presentation/CustomerRegistrationPresenterTest.cs b/slips/src/test/Marina.Test/Unit/Presentation/CustomerRegistrationPresenterTest.cs new file mode 100644 index 0000000..e571683 --- /dev/null +++ b/slips/src/test/Marina.Test/Unit/Presentation/CustomerRegistrationPresenterTest.cs @@ -0,0 +1,69 @@ +using System.Collections.Generic; +using Marina.Presentation.DTO; +using Marina.Presentation.Mappers; +using Marina.Presentation.Presenters; +using Marina.Presentation.Views; +using Marina.Task; +using Marina.Test.Utility; +using MbUnit.Framework; +using Rhino.Mocks; + +namespace Marina.Test.Unit.Presentation { + [TestFixture] + public class CustomerRegistrationPresenterTest { + private MockRepository mockery; + private ICustomerRegistrationPresentationMapper mockMapper; + private ICustomerRegistrationView mockView; + private IRegistrationTasks mockTask; + + [SetUp] + public void SetUp( ) { + mockery = new MockRepository( ); + mockMapper = mockery.DynamicMock< ICustomerRegistrationPresentationMapper >( ); + mockView = mockery.DynamicMock< ICustomerRegistrationView >( ); + mockTask = mockery.DynamicMock< IRegistrationTasks >( ); + } + + [Test] + public void Should_leverage_mapper_to_convert_view_data_to_dto( ) { + using ( mockery.Record( ) ) { + Expect.Call( mockMapper.MapFrom( mockView ) ).Return( null ); + } + + using ( mockery.Playback( ) ) { + CreateSUT( ).RegisterCustomer( ); + } + } + + [Test] + public void Should_leverage_task_to_submit_new_registration_information( ) { + RegisterCustomerDTO customerRegistrationDTO = ObjectMother.CustomerRegistrationDTO( ); + using ( mockery.Record( ) ) { + SetupResult.For( mockMapper.MapFrom( mockView ) ).Return( customerRegistrationDTO ); + Expect.Call( mockTask.RegisterNew( customerRegistrationDTO ) ).Return( null ); + } + + using ( mockery.Playback( ) ) { + CreateSUT( ).RegisterCustomer( ); + } + } + + [Test] + public void Should_display_response_on_view( ) { + IEnumerable< DisplayResponseLineDTO > responseDTO = + ObjectMother.EnumerableDisplayResponseLineDTO( ); + using ( mockery.Record( ) ) { + SetupResult.For( mockTask.RegisterNew( null ) ).IgnoreArguments( ).Return( responseDTO ); + mockView.Display( responseDTO ); + } + + using ( mockery.Playback( ) ) { + CreateSUT( ).RegisterCustomer( ); + } + } + + private ICustomerRegistrationPresenter CreateSUT( ) { + return new CustomerRegistrationPresenter( mockView, mockMapper, mockTask ); + } + } +} \ No newline at end of file diff --git a/slips/src/test/Marina.Test/Unit/Presentation/DockPresenterTest.cs b/slips/src/test/Marina.Test/Unit/Presentation/DockPresenterTest.cs new file mode 100644 index 0000000..1fc2a26 --- /dev/null +++ b/slips/src/test/Marina.Test/Unit/Presentation/DockPresenterTest.cs @@ -0,0 +1,90 @@ +using System.Collections.Generic; +using Marina.Presentation; +using Marina.Presentation.DTO; +using Marina.Presentation.Presenters; +using Marina.Presentation.Views; +using Marina.Task; +using Marina.Test.Utility; +using Marina.Web; +using MbUnit.Framework; +using Rhino.Mocks; + +namespace Marina.Test.Unit.Presentation { + [TestFixture] + public class DockPresenterTest { + private MockRepository mockery; + private IDockView mockView; + private ICatalogTasks mockTask; + private IHttpRequest mockRequest; + + private IDockPresenter CreateSUT( ) { + return new DockPresenter( mockView, mockRequest, mockTask ); + } + + [SetUp] + public void SetUp( ) { + mockery = new MockRepository( ); + mockView = mockery.DynamicMock< IDockView >( ); + mockTask = mockery.DynamicMock< ICatalogTasks >( ); + mockRequest = mockery.DynamicMock< IHttpRequest >( ); + } + + [Test] + public void Should_leverage_its_task_to_retrieve_the_dock_information( ) { + long dockId = 1; + using ( mockery.Record( ) ) { + SetupResult.For( mockRequest.ParsePayloadFor( PayloadKeys.DockId ) ).Return( dockId ); + Expect.Call( mockTask.GetDockInformationBy( dockId ) ).Return( null ); + } + using ( mockery.Playback( ) ) { + CreateSUT( ).Initialize( ); + } + } + + [Test] + public void Should_display_dock_information( ) { + DockDisplayDTO dto = ObjectMother.DockDisplayDTO( ); + int dockId = 2; + + using ( mockery.Record( ) ) { + SetupResult.For( mockRequest.ParsePayloadFor( PayloadKeys.DockId ) ).Return( dockId ); + SetupResult.For( mockTask.GetDockInformationBy( dockId ) ).Return( dto ); + mockView.Display( dto ); + } + + using ( mockery.Playback( ) ) { + CreateSUT( ).Initialize( ); + } + } + + [Test] + public void Should_leverage_task_to__load_list_of_locations_on_initialize( ) { + long dockId = 1; + + using ( mockery.Record( ) ) { + SetupResult.For( mockRequest.ParsePayloadFor( PayloadKeys.DockId ) ).Return( dockId ); + Expect.Call( mockTask.GetAvailableSlipsForDockBy( dockId ) ).Return( null ); + } + + using ( mockery.Playback( ) ) { + CreateSUT( ).Initialize( ); + } + } + + [Test] + public void Should_display_the_available_slips( ) { + IEnumerable< SlipDisplayDTO > availableSlips = new List< SlipDisplayDTO >( ); + long dockId = 2; + + using ( mockery.Record( ) ) { + SetupResult.For( mockRequest.ParsePayloadFor( PayloadKeys.DockId ) ).Return( dockId ); + SetupResult.For( mockTask.GetAvailableSlipsForDockBy( dockId ) ).Return( availableSlips ); + mockView.Display( availableSlips ); + } + + using ( mockery.Playback( ) ) { + CreateSUT( ).Initialize( ); + } + } + } +} \ No newline at end of file diff --git a/slips/src/test/Marina.Test/Unit/Presentation/LeaseSlipPresenterTest.cs b/slips/src/test/Marina.Test/Unit/Presentation/LeaseSlipPresenterTest.cs new file mode 100644 index 0000000..d53f9f9 --- /dev/null +++ b/slips/src/test/Marina.Test/Unit/Presentation/LeaseSlipPresenterTest.cs @@ -0,0 +1,100 @@ +using Marina.Presentation; +using Marina.Presentation.DTO; +using Marina.Presentation.Mappers; +using Marina.Presentation.Presenters; +using Marina.Presentation.Views; +using Marina.Task; +using Marina.Test.Utility; +using Marina.Web; +using MbUnit.Framework; +using Rhino.Mocks; + +namespace Marina.Test.Unit.Presentation { + [TestFixture] + public class LeaseSlipPresenterTest { + private MockRepository _mockery; + private IHttpRequest _mockRequest; + private ICatalogTasks _mockTask; + private ILeaseSlipView _mockView; + private ILeaseTasks _mockLeaseTasks; + private ILeaseRequestDtoFromHttpRequestMapper _mockMapper; + + [SetUp] + public void Setup() { + _mockery = new MockRepository( ); + _mockRequest = _mockery.DynamicMock< IHttpRequest >( ); + _mockTask = _mockery.DynamicMock< ICatalogTasks >( ); + _mockLeaseTasks = _mockery.DynamicMock< ILeaseTasks >( ); + _mockView = _mockery.DynamicMock< ILeaseSlipView >( ); + + _mockMapper = _mockery.DynamicMock< ILeaseRequestDtoFromHttpRequestMapper >( ); + } + + public ILeaseSlipPresenter CreateSUT() { + return new LeaseSlipPresenter( _mockView, _mockRequest, _mockTask, _mockLeaseTasks, _mockMapper ); + } + + [Test] + public void Should_leverage_task_to_retrieve_information_on_slip() { + long slipId = 66; + SlipDisplayDTO slip = ObjectMother.SlipDisplayDTO( ); + using ( _mockery.Record( ) ) { + SetupResult.For( _mockRequest.ParsePayloadFor( PayloadKeys.SlipId ) ).Return( slipId ); + Expect.Call( _mockTask.FindSlipBy( slipId ) ).Return( slip ); + } + + using ( _mockery.Playback( ) ) { + CreateSUT( ).Initialize( ); + } + } + + [Test] + public void Should_display_found_slip_on_view() { + SlipDisplayDTO slip = ObjectMother.SlipDisplayDTO( ); + using ( _mockery.Record( ) ) { + SetupResult.For( _mockTask.FindSlipBy( 0 ) ).IgnoreArguments( ).Return( slip ); + _mockView.Display( slip ); + } + + using ( _mockery.Playback( ) ) { + CreateSUT( ).Initialize( ); + } + } + + [Test] + public void Should_save_lease_slip_when_customer_submits_a_request() { + long customerId = 2; + long slipId = 3; + + SubmitLeaseRequestDTO request = new SubmitLeaseRequestDTO( customerId, slipId, "weekly" ); + DisplayResponseLineDTO response = new DisplayResponseLineDTO( "" ); + + using ( _mockery.Record( ) ) { + SetupResult.For( _mockMapper.MapFrom( _mockRequest ) ).Return( request ); + Expect.Call( _mockLeaseTasks.RequestLeaseUsing( request ) ).Return( response ); + } + + using ( _mockery.Playback( ) ) { + CreateSUT( ).SubmitLeaseRequest( ); + } + } + + [Test] + public void Should_display_response_from_lease_request_on_the_view() { + SubmitLeaseRequestDTO request = new SubmitLeaseRequestDTO( 1, 1, "weekly" ); + DisplayResponseLineDTO response = new DisplayResponseLineDTO( "" ); + + using ( _mockery.Record( ) ) { + SetupResult + .For( _mockLeaseTasks.RequestLeaseUsing( request ) ) + .IgnoreArguments( ) + .Return( response ); + _mockView.Display( response ); + } + + using ( _mockery.Playback( ) ) { + CreateSUT( ).SubmitLeaseRequest( ); + } + } + } +} \ No newline at end of file diff --git a/slips/src/test/Marina.Test/Unit/Presentation/LoginPresenterTest.cs b/slips/src/test/Marina.Test/Unit/Presentation/LoginPresenterTest.cs new file mode 100644 index 0000000..d5dd994 --- /dev/null +++ b/slips/src/test/Marina.Test/Unit/Presentation/LoginPresenterTest.cs @@ -0,0 +1,62 @@ +using Marina.Presentation.DTO; +using Marina.Presentation.Mappers; +using Marina.Presentation.Presenters; +using Marina.Presentation.Views; +using Marina.Task; +using Marina.Test.Utility; +using Marina.Web; +using MbUnit.Framework; +using Rhino.Mocks; + +namespace Marina.Test.Unit.Presentation { + [TestFixture] + public class LoginPresenterTest { + private MockRepository mockery; + private ILoginView mockView; + private IAuthenticationTask mockTask; + private ILoginCredentialsMapper mockMapper; + private IHttpRequest mockRequest; + + [SetUp] + public void SetUp() { + mockery = new MockRepository( ); + mockView = mockery.DynamicMock< ILoginView >( ); + mockTask = mockery.DynamicMock< IAuthenticationTask >( ); + mockRequest = mockery.DynamicMock< IHttpRequest >( ); + mockMapper = mockery.DynamicMock< ILoginCredentialsMapper >( ); + } + + [Test] + public void Should_leverage_task_to_check_if_credentials_are_correct() { + LoginCredentialsDTO credentials = ObjectMother.LoginCredentialsDTO( ); + using ( mockery.Record( ) ) { + SetupResult.For( mockMapper.MapFrom( mockRequest ) ).Return( credentials ); + Expect.Call( mockTask.AuthenticateUserUsing( credentials ) ).Return( null ); + } + + using ( mockery.Playback( ) ) { + CreateSUT( ).Login( ); + } + } + + [Test] + public void Should_display_response_messages_from_task() { + DisplayResponseLineDTO responseMessage = ObjectMother.DisplayResponseLineDTO( ); + using ( mockery.Record( ) ) { + SetupResult + .For( mockTask.AuthenticateUserUsing( null ) ) + .IgnoreArguments( ) + .Return( responseMessage ); + mockView.Display( responseMessage ); + } + + using ( mockery.Playback( ) ) { + CreateSUT( ).Login( ); + } + } + + private ILoginPresenter CreateSUT() { + return new LoginPresenter( mockView, mockRequest, mockTask, mockMapper ); + } + } +} \ No newline at end of file diff --git a/slips/src/test/Marina.Test/Unit/Presentation/Mappers/CustomerRegistrationPresentationMapperTest.cs b/slips/src/test/Marina.Test/Unit/Presentation/Mappers/CustomerRegistrationPresentationMapperTest.cs new file mode 100644 index 0000000..29f9d21 --- /dev/null +++ b/slips/src/test/Marina.Test/Unit/Presentation/Mappers/CustomerRegistrationPresentationMapperTest.cs @@ -0,0 +1,52 @@ +using Marina.Presentation.DTO; +using Marina.Presentation.Mappers; +using Marina.Presentation.Views; +using MbUnit.Framework; +using Rhino.Mocks; + +namespace Marina.Test.Unit.Presentation.Mappers { + [TestFixture] + public class CustomerRegistrationPresentationMapperTest { + private MockRepository mockery; + + [SetUp] + public void SetUp( ) { + mockery = new MockRepository( ); + } + + [Test] + public void Should_map_view_data_to_dto( ) { + ICustomerRegistrationView mockView = mockery.DynamicMock< ICustomerRegistrationView >( ); + string userName = "mrMO"; + string password = "password"; + string firstName = "mo"; + string lastName = "khan"; + string phoneNumber = "(403)6813389"; + string city = "calgary"; + + using ( mockery.Record( ) ) { + SetupResult.For( mockView.UserName( ) ).Return( userName ); + SetupResult.For( mockView.Password( ) ).Return( password ); + SetupResult.For( mockView.FirstName( ) ).Return( firstName ); + SetupResult.For( mockView.LastName( ) ).Return( lastName ); + SetupResult.For( mockView.PhoneNumber( ) ).Return( phoneNumber ); + SetupResult.For( mockView.City( ) ).Return( city ); + } + + using ( mockery.Playback( ) ) { + RegisterCustomerDTO mappedDTO = CreateSUT( ).MapFrom( mockView ); + + Assert.AreEqual( mappedDTO.UserName, userName ); + Assert.AreEqual( mappedDTO.Password, password ); + Assert.AreEqual( mappedDTO.FirstName, firstName ); + Assert.AreEqual( mappedDTO.LastName, lastName ); + Assert.AreEqual( mappedDTO.Phone, phoneNumber ); + Assert.AreEqual( mappedDTO.City, city ); + } + } + + private ICustomerRegistrationPresentationMapper CreateSUT( ) { + return new CustomerRegistrationPresentationMapper( ); + } + } +} \ No newline at end of file diff --git a/slips/src/test/Marina.Test/Unit/Presentation/Mappers/LoginCredentialsMapperTest.cs b/slips/src/test/Marina.Test/Unit/Presentation/Mappers/LoginCredentialsMapperTest.cs new file mode 100644 index 0000000..4dae259 --- /dev/null +++ b/slips/src/test/Marina.Test/Unit/Presentation/Mappers/LoginCredentialsMapperTest.cs @@ -0,0 +1,35 @@ +using Marina.Presentation; +using Marina.Presentation.Mappers; +using Marina.Web; +using MbUnit.Framework; +using Rhino.Mocks; + +namespace Marina.Test.Unit.Presentation.Mappers { + [TestFixture] + public class LoginCredentialsMapperTest { + private MockRepository mockery; + private IHttpRequest mockRequest; + + [SetUp] + public void SetUp( ) { + mockery = new MockRepository( ); + mockRequest = mockery.DynamicMock< IHttpRequest >( ); + } + + [Test] + public void Should_map_username_from_request( ) { + using ( mockery.Record( ) ) { + Expect.Call( mockRequest.ParsePayloadFor( PayloadKeys.For( "uxUserNameTextBox" ) ) ).Return( null ); + Expect.Call( mockRequest.ParsePayloadFor( PayloadKeys.For( "uxPasswordTextBox" ) ) ).Return( null ); + } + + using ( mockery.Playback( ) ) { + CreateSUT( ).MapFrom( mockRequest ); + } + } + + private LoginCredentialsMapper CreateSUT( ) { + return new LoginCredentialsMapper( ); + } + } +} \ No newline at end of file diff --git a/slips/src/test/Marina.Test/Unit/Presentation/Mappers/UpdateRegistrationPresentationMapperTest.cs b/slips/src/test/Marina.Test/Unit/Presentation/Mappers/UpdateRegistrationPresentationMapperTest.cs new file mode 100644 index 0000000..510756f --- /dev/null +++ b/slips/src/test/Marina.Test/Unit/Presentation/Mappers/UpdateRegistrationPresentationMapperTest.cs @@ -0,0 +1,57 @@ +using Marina.Presentation; +using Marina.Presentation.DTO; +using Marina.Presentation.Mappers; +using Marina.Web; +using MbUnit.Framework; +using Rhino.Mocks; + +namespace Marina.Test.Unit.Presentation.Mappers { + [TestFixture] + public class UpdateRegistrationPresentationMapperTest { + private MockRepository mockery; + private IHttpRequest mockRequest; + + [SetUp] + public void SetUp( ) { + mockery = new MockRepository( ); + mockRequest = mockery.DynamicMock< IHttpRequest >( ); + } + + [RowTest] + [Row( 0, "username", "password", "mo", "khan", "4036813389", "calgary" )] + [Row( 0, "username1", "p@ssword", "m0", "khAAn", "d33d9", "toronto" )] + [Row( 0, "username2", "passw0rd", "m1", "kh@n", "4036d333389", "new york" )] + public void Should_map_the_data_from_the_view_to_the_dto( long customerId, string userName, string password, + string firstName, + string lastName, string phone, string city ) { + using ( mockery.Record( ) ) { + SetupResult.For( mockRequest.ParsePayloadFor( PayloadKeys.CustomerId ) ).Return( customerId ); + SetupResult.For( mockRequest.ParsePayloadFor( Create( "uxUserNameTextBox" ) ) ).Return( userName ); + SetupResult.For( mockRequest.ParsePayloadFor( Create( "uxPasswordTextBox" ) ) ).Return( password ); + SetupResult.For( mockRequest.ParsePayloadFor( Create( "uxFirstNameTextBox" ) ) ).Return( firstName ); + SetupResult.For( mockRequest.ParsePayloadFor( Create( "uxLastNameTextBox" ) ) ).Return( lastName ); + SetupResult.For( mockRequest.ParsePayloadFor( Create( "uxPhoneNumberTextBox" ) ) ).Return( phone ); + SetupResult.For( mockRequest.ParsePayloadFor( Create( "uxCityTextBox" ) ) ).Return( city ); + } + + using ( mockery.Playback( ) ) { + UpdateCustomerRegistrationDTO dto = CreateSUT( ).MapFrom( mockRequest ); + Assert.AreEqual( customerId, dto.CustomerId ); + Assert.AreEqual( userName, dto.Username ); + Assert.AreEqual( password, dto.Password ); + Assert.AreEqual( firstName, dto.FirstName ); + Assert.AreEqual( lastName, dto.LastName ); + Assert.AreEqual( phone, dto.PhoneNumber ); + Assert.AreEqual( city, dto.City ); + } + } + + public PayloadKey< string > Create( string controlId ) { + return PayloadKeys.For( controlId ); + } + + private IUpdateRegistrationPresentationMapper CreateSUT( ) { + return new UpdateRegistrationPresentationMapper( ); + } + } +} \ No newline at end of file diff --git a/slips/src/test/Marina.Test/Unit/Presentation/PayloadKeyTest.cs b/slips/src/test/Marina.Test/Unit/Presentation/PayloadKeyTest.cs new file mode 100644 index 0000000..b7a3540 --- /dev/null +++ b/slips/src/test/Marina.Test/Unit/Presentation/PayloadKeyTest.cs @@ -0,0 +1,45 @@ +using System; +using System.Collections.Specialized; +using Marina.Presentation; +using MbUnit.Framework; + +namespace Marina.Test.Unit.Presentation { + [TestFixture] + public class PayloadKeyTest { + [Test] + public void Should_be_able_to_convert_an_item_from_the_payload_into_an_item_of_the_correct_type( ) { + string key = "DID"; + int expectedValue = 1; + + NameValueCollection payload = new NameValueCollection( ); + payload.Add( key, expectedValue.ToString( ) ); + + int actualValue = CreateSUT< int >( key ).ParseFrom( payload ); + Assert.AreEqual( expectedValue, actualValue ); + } + + [Test] + [ExpectedException( typeof( Exception ) )] + public void Should_not_be_able_to_parse_if_the_item_in_the_payload_does_not_match_the_data_type_for_the_key( ) { + NameValueCollection payload = new NameValueCollection( ); + payload.Add( "DID", "NotAnInt" ); + CreateSUT< int >( "DID" ).ParseFrom( payload ); + } + + [Test] + public void Should_be_able_to_implicitly_cast_to_a_string( ) { + string implictlyCasted = CreateSUT< int >( "DID" ); + Assert.AreEqual( "DID", implictlyCasted ); + } + + [Test] + [ExpectedException( typeof( PayloadKeyNotFoundException ) )] + public void Should_return_default_value_if_key_is_not_in_payload( ) { + CreateSUT< string >( "NOTINPAYLOAD" ).ParseFrom( new NameValueCollection( ) ); + } + + private PayloadKey< T > CreateSUT< T >( string key ) { + return new PayloadKey< T >( key ); + } + } +} \ No newline at end of file diff --git a/slips/src/test/Marina.Test/Unit/Presentation/RegisterBoatPresenterTest.cs b/slips/src/test/Marina.Test/Unit/Presentation/RegisterBoatPresenterTest.cs new file mode 100644 index 0000000..2daf6f2 --- /dev/null +++ b/slips/src/test/Marina.Test/Unit/Presentation/RegisterBoatPresenterTest.cs @@ -0,0 +1,67 @@ +using System.Collections.Generic; +using Marina.Presentation.DTO; +using Marina.Presentation.Mappers; +using Marina.Presentation.Presenters; +using Marina.Presentation.Views; +using Marina.Task; +using Marina.Test.Utility; +using Marina.Web; +using MbUnit.Framework; +using Rhino.Mocks; + +namespace Marina.Test.Unit.Presentation { + [TestFixture] + public class RegisterBoatPresenterTest { + private MockRepository mockery; + private IRegisterBoatView mockView; + private IRegistrationTasks mockTask; + private IHttpRequest mockRequest; + private INewBoatRegistrationMapper mockMapper; + + [SetUp] + public void SetUp() { + mockery = new MockRepository( ); + mockView = mockery.DynamicMock< IRegisterBoatView >( ); + mockTask = mockery.DynamicMock< IRegistrationTasks >( ); + mockRequest = mockery.DynamicMock< IHttpRequest >( ); + mockMapper = mockery.DynamicMock< INewBoatRegistrationMapper >( ); + } + + [Test] + public void Should_leverage_task_to_submit_new_boat_registration() { + IEnumerable< DisplayResponseLineDTO > response = ObjectMother.EnumerableDisplayResponseLineDTO( ); + BoatRegistrationDTO boat = ObjectMother.BoatRegistrationDTO( ); + + using ( mockery.Record( ) ) { + SetupResult.For( mockMapper.MapFrom( mockRequest ) ).Return( boat ); + + Expect.Call( mockTask.AddNewBoatUsing( boat ) ).Return( response ); + } + + using ( mockery.Playback( ) ) { + CreateSUT( ).SubmitRegistration( ); + } + } + + [Test] + public void Should_display_response_from_task_on_view() { + IEnumerable< DisplayResponseLineDTO > response = ObjectMother.EnumerableDisplayResponseLineDTO( ); + BoatRegistrationDTO boat = ObjectMother.BoatRegistrationDTO( ); + + using ( mockery.Record( ) ) { + SetupResult.For( mockMapper.MapFrom( mockRequest ) ).Return( boat ); + SetupResult.For( mockTask.AddNewBoatUsing( boat ) ).Return( response ); + + mockView.Display( response ); + } + + using ( mockery.Playback( ) ) { + CreateSUT( ).SubmitRegistration( ); + } + } + + private IRegisterBoatPresenter CreateSUT() { + return new RegisterBoatPresenter( mockView, mockRequest, mockTask, mockMapper ); + } + } +} \ No newline at end of file diff --git a/slips/src/test/Marina.Test/Unit/Presentation/UpdateRegistrationPresenterTest.cs b/slips/src/test/Marina.Test/Unit/Presentation/UpdateRegistrationPresenterTest.cs new file mode 100644 index 0000000..753ee83 --- /dev/null +++ b/slips/src/test/Marina.Test/Unit/Presentation/UpdateRegistrationPresenterTest.cs @@ -0,0 +1,92 @@ +using System.Collections.Generic; +using Marina.Presentation; +using Marina.Presentation.DTO; +using Marina.Presentation.Mappers; +using Marina.Presentation.Presenters; +using Marina.Presentation.Views; +using Marina.Task; +using Marina.Test.Utility; +using Marina.Web; +using MbUnit.Framework; +using Rhino.Mocks; + +namespace Marina.Test.Unit.Presentation { + [TestFixture] + public class UpdateRegistrationPresenterTest { + private MockRepository mockery; + private IRegistrationTasks mockTask; + private IUpdateRegistrationView mockView; + private IUpdateRegistrationPresentationMapper mockMapper; + private IHttpRequest mockRequest; + + [SetUp] + public void SetUp( ) { + mockery = new MockRepository( ); + mockView = mockery.DynamicMock< IUpdateRegistrationView >( ); + mockTask = mockery.DynamicMock< IRegistrationTasks >( ); + mockMapper = mockery.DynamicMock< IUpdateRegistrationPresentationMapper >( ); + mockRequest = mockery.DynamicMock< IHttpRequest >( ); + } + + [Test] + public void Should_leverage_task_to_load_current_registration_information_for_customer( ) { + int customerId = 1; + + using ( mockery.Record( ) ) { + SetupResult.For( mockRequest.ParsePayloadFor( PayloadKeys.CustomerId ) ).Return( customerId ); + Expect.Call( mockTask.LoadRegistrationFor( customerId ) ).Return( null ); + } + + using ( mockery.Playback( ) ) { + CreateSUT( ).Initialize( ); + } + } + + [Test] + public void Should_display_the_customer_registration_information_in_the_view( ) { + int customerId = 1; + CustomerRegistrationDisplayDTO customerRegistration = ObjectMother.DisplayCustomerRegistrationDTO( ); + using ( mockery.Record( ) ) { + SetupResult.For( mockRequest.ParsePayloadFor( PayloadKeys.CustomerId ) ).Return( customerId ); + SetupResult.For( mockTask.LoadRegistrationFor( customerId ) ).Return( customerRegistration ); + mockView.Display( customerRegistration ); + } + using ( mockery.Playback( ) ) { + CreateSUT( ).Initialize( ); + } + } + + [Test] + public void Should_leverage_task_to_submit_changed_registration_information( ) { + UpdateCustomerRegistrationDTO customer = ObjectMother.UpdateCustomerRegistrationDTO( ); + + using ( mockery.Record( ) ) { + SetupResult.For( mockMapper.MapFrom( mockRequest ) ).Return( customer ); + Expect.Call( mockTask.UpdateRegistrationFor( customer ) ).Return( null ); + } + + using ( mockery.Playback( ) ) { + CreateSUT( ).UpdateRegistration( ); + } + } + + [Test] + public void Should_display_response_on_view( ) { + IEnumerable< DisplayResponseLineDTO > responseDTO = + ObjectMother.EnumerableDisplayResponseLineDTO( ); + + using ( mockery.Record( ) ) { + SetupResult.For( mockTask.UpdateRegistrationFor( null ) ).IgnoreArguments( ).Return( responseDTO ); + mockView.Display( responseDTO ); + } + + using ( mockery.Playback( ) ) { + CreateSUT( ).UpdateRegistration( ); + } + } + + private IUpdateCustomerRegistrationPresenter CreateSUT( ) { + return new UpdateCustomerRegistrationPresenter( mockView, mockRequest, mockTask, mockMapper ); + } + } +} \ No newline at end of file diff --git a/slips/src/test/Marina.Test/Unit/Presentation/ViewRegisteredBoatsPresenterTest.cs b/slips/src/test/Marina.Test/Unit/Presentation/ViewRegisteredBoatsPresenterTest.cs new file mode 100644 index 0000000..1443153 --- /dev/null +++ b/slips/src/test/Marina.Test/Unit/Presentation/ViewRegisteredBoatsPresenterTest.cs @@ -0,0 +1,62 @@ +using System.Collections.Generic; +using Marina.Presentation; +using Marina.Presentation.DTO; +using Marina.Presentation.Presenters; +using Marina.Presentation.Views; +using Marina.Task; +using Marina.Web; +using MbUnit.Framework; +using Rhino.Mocks; + +namespace Marina.Test.Unit.Presentation { + [TestFixture] + public class ViewRegisteredBoatsPresenterTest { + private MockRepository _mockery; + private IRegistrationTasks _mockTask; + private IHttpRequest _mockRequest; + private IRegisteredBoatsView _mockView; + + [SetUp] + public void Setup() { + _mockery = new MockRepository( ); + _mockTask = _mockery.DynamicMock< IRegistrationTasks >( ); + _mockRequest = _mockery.DynamicMock< IHttpRequest >( ); + _mockView = _mockery.DynamicMock< IRegisteredBoatsView >( ); + } + + public IViewRegisteredBoatsPresenter CreateSUT() { + return new ViewRegisteredBoatsPresenter( _mockView, _mockTask, _mockRequest ); + } + + [Test] + public void Should_leverage_task_to_retrieve_all_registered_boats_for_customer() { + long customerId = 23; + IList< BoatRegistrationDTO > boats = new List< BoatRegistrationDTO >( ); + + using ( _mockery.Record( ) ) { + SetupResult.For( _mockRequest.ParsePayloadFor( PayloadKeys.CustomerId ) ).Return( customerId ); + Expect.Call( _mockTask.AllBoatsFor( customerId ) ).Return( boats ); + } + + using ( _mockery.Playback( ) ) { + CreateSUT( ).Initialize( ); + } + } + + [Test] + public void Should_display_registered_boats_on_view() { + IList< BoatRegistrationDTO > boats = new List< BoatRegistrationDTO >( ); + using ( _mockery.Record( ) ) { + SetupResult.For( _mockTask.AllBoatsFor( 0 ) ) + .IgnoreArguments( ) + .Return( boats ); + + _mockView.Display( boats ); + } + + using ( _mockery.Playback( ) ) { + CreateSUT( ).Initialize( ); + } + } + } +} \ No newline at end of file diff --git a/slips/src/test/Marina.Test/Unit/Task/CatalogTasksTest.cs b/slips/src/test/Marina.Test/Unit/Task/CatalogTasksTest.cs new file mode 100644 index 0000000..1eae132 --- /dev/null +++ b/slips/src/test/Marina.Test/Unit/Task/CatalogTasksTest.cs @@ -0,0 +1,106 @@ +using System.Collections.Generic; +using Marina.Domain.Interfaces; +using Marina.Domain.Repositories; +using Marina.Infrastructure; +using Marina.Presentation.DTO; +using Marina.Task; +using Marina.Task.Mappers; +using Marina.Test.Utility; +using MbUnit.Framework; +using Rhino.Mocks; + +namespace Marina.Test.Unit.Task { + [TestFixture] + public class CatalogTasksTest { + private MockRepository _mockery; + private ISlipsRepository _slipRepository; + private ISlipsToDisplayDTOMapper _slipMapper; + private IDockRepository _dockRepository; + private IDockToDisplayDTOMapper _dockMapper; + + [SetUp] + public void Setup() { + _mockery = new MockRepository( ); + _slipRepository = _mockery.DynamicMock< ISlipsRepository >( ); + _dockRepository = _mockery.DynamicMock< IDockRepository >( ); + _slipMapper = _mockery.DynamicMock< ISlipsToDisplayDTOMapper >( ); + _dockMapper = _mockery.DynamicMock< IDockToDisplayDTOMapper >( ); + } + + public ICatalogTasks CreateSUT() { + return new CatalogTasks( _slipRepository, _slipMapper, _dockRepository, _dockMapper ); + } + + [Test] + public void Should_leverage_mapper_to_map_all_slips() { + IList< ISlip > availableSlips = new List< ISlip >( ); + ISlip slip = _mockery.DynamicMock< ISlip >( ); + + availableSlips.Add( slip ); + + SlipDisplayDTO slipDTO = ObjectMother.SlipDisplayDTO( ); + + using ( _mockery.Record( ) ) { + SetupResult.For( _slipRepository.AllAvailableSlips( ) ).Return( availableSlips ); + Expect.Call( _slipMapper.MapFrom( slip ) ).Return( slipDTO ); + } + + using ( _mockery.Playback( ) ) { + IEnumerable< SlipDisplayDTO > allAvailableSlips = CreateSUT( ).GetAllAvailableSlips( ); + Assert.IsTrue( ListFactory.From( allAvailableSlips ).Contains( slipDTO ) ); + } + } + + [Test] + public void Should_leverage_repository_to_find_dock_by_id() { + long dockId = 1; + IDock dock = _mockery.DynamicMock< IDock >( ); + + using ( _mockery.Record( ) ) { + Expect.Call( _dockRepository.FindBy( dockId ) ).Return( dock ); + } + + using ( _mockery.Playback( ) ) { + CreateSUT( ).GetDockInformationBy( dockId ); + } + } + + [Test] + public void Should_leverage_mapper_to_return_dto() { + long dockId = 1; + IDock dock = _mockery.DynamicMock< IDock >( ); + + DockDisplayDTO dto = ObjectMother.DockDisplayDTO( ); + using ( _mockery.Record( ) ) { + SetupResult.For( _dockRepository.FindBy( dockId ) ).Return( dock ); + Expect.Call( _dockMapper.MapFrom( dock ) ).Return( dto ); + } + + using ( _mockery.Playback( ) ) { + Assert.AreEqual( dto, CreateSUT( ).GetDockInformationBy( dockId ) ); + } + } + + [Test] + public void Should_leverage_repository_to_find_dock() { + long dockId = 1; + IDock dock = _mockery.DynamicMock< IDock >( ); + ISlip slip = _mockery.DynamicMock< ISlip >( ); + + IList< ISlip > availableSlipsForDock = new List< ISlip >( ); + availableSlipsForDock.Add( slip ); + + SlipDisplayDTO dto = ObjectMother.SlipDisplayDTO( ); + using ( _mockery.Record( ) ) { + Expect.Call( _dockRepository.FindBy( dockId ) ).Return( dock ); + Expect.Call( _slipRepository.AllAvailableSlipsFor( dock ) ).Return( availableSlipsForDock ); + Expect.Call( _slipMapper.MapFrom( slip ) ).Return( dto ); + } + + using ( _mockery.Playback( ) ) { + IRichList< SlipDisplayDTO > slipsFound = ListFactory.From( CreateSUT( ).GetAvailableSlipsForDockBy( dockId ) ); + Assert.IsTrue( slipsFound.Contains( dto ) ); + } + } + } +} \ No newline at end of file diff --git a/slips/src/test/Marina.Test/Unit/Task/LeaseTasksTest.cs b/slips/src/test/Marina.Test/Unit/Task/LeaseTasksTest.cs new file mode 100644 index 0000000..e645640 --- /dev/null +++ b/slips/src/test/Marina.Test/Unit/Task/LeaseTasksTest.cs @@ -0,0 +1,181 @@ +using Marina.Domain; +using Marina.Domain.Exceptions; +using Marina.Domain.Interfaces; +using Marina.Domain.Repositories; +using Marina.Infrastructure; +using Marina.Presentation.DTO; +using Marina.Task; +using Marina.Task.Mappers; +using MbUnit.Framework; +using Rhino.Mocks; + +namespace Marina.Test.Unit.Task { + [TestFixture] + public class LeaseTasksTest { + private MockRepository _mockery; + private ICustomerRepository _customers; + private ILeaseToDtoMapper _mapper; + private ISlipsRepository _slips; + + [SetUp] + public void Setup() { + _mockery = new MockRepository( ); + _customers = _mockery.DynamicMock< ICustomerRepository >( ); + _slips = _mockery.DynamicMock< ISlipsRepository >( ); + _mapper = _mockery.DynamicMock< ILeaseToDtoMapper >( ); + } + + public ILeaseTasks CreateSUT() { + return new LeaseTasks( _customers, _slips, _mapper ); + } + + [Test] + public void Should_leverage_repository_to_find_customer() { + long customerId = 87; + + using ( _mockery.Record( ) ) { + Expect.Call( _customers.FindBy( customerId ) ).Return( _mockery.DynamicMock< ICustomer >( ) ); + } + + using ( _mockery.Playback( ) ) { + CreateSUT( ).FindAllLeasesFor( customerId ); + } + } + + [Test] + public void Should_leverage_mapper_to_convert_to_dto() { + long customerId = 99; + ICustomer customer = _mockery.DynamicMock< ICustomer >( ); + ISlipLease lease = _mockery.DynamicMock< ISlipLease >( ); + DisplayLeaseDTO dto = new DisplayLeaseDTO( "", "", "" ); + + using ( _mockery.Record( ) ) { + SetupResult.For( customer.Leases( ) ).Return( ListFactory.For( lease ) ); + SetupResult.For( _customers.FindBy( customerId ) ).Return( customer ); + Expect.Call( _mapper.MapFrom( lease ) ).Return( dto ); + } + + using ( _mockery.Playback( ) ) { + IRichList< DisplayLeaseDTO > returnedDtos = ListFactory.From( CreateSUT( ).FindAllLeasesFor( customerId ) ); + Assert.AreEqual( 1, returnedDtos.Count ); + Assert.IsTrue( returnedDtos.Contains( dto ) ); + } + } + + [Test] + public void Should_lookup_customer_from_repository_when_requesting_a_lease() { + long customerId = 87; + long slipId = 32; + SubmitLeaseRequestDTO request = new SubmitLeaseRequestDTO( customerId, slipId, "daily" ); + ICustomer customer = _mockery.DynamicMock< ICustomer >( ); + + using ( _mockery.Record( ) ) { + Expect.Call( _customers.FindBy( customerId ) ).Return( customer ); + } + + using ( _mockery.Playback( ) ) { + CreateSUT( ).RequestLeaseUsing( request ); + } + } + + [RowTest] + [Row( 99 )] + [Row( 87 )] + public void Should_lookup_slip_from_repository_when_requesting_a_lease( long slipId ) { + long customerId = 87; + SubmitLeaseRequestDTO request = new SubmitLeaseRequestDTO( customerId, slipId, "weekly" ); + ISlip slip = _mockery.DynamicMock< ISlip >( ); + ICustomer customer = _mockery.DynamicMock< ICustomer >( ); + + using ( _mockery.Record( ) ) { + SetupResult.For( _customers.FindBy( 0 ) ).IgnoreArguments( ).Return( customer ); + Expect.Call( _slips.FindBy( slipId ) ).Return( slip ); + } + + using ( _mockery.Playback( ) ) { + CreateSUT( ).RequestLeaseUsing( request ); + } + } + + [Test] + public void customer_should_attempt_to_lease_slip() { + long customerId = 87; + long slipId = 32; + + string duration = "weekly"; + SubmitLeaseRequestDTO request = new SubmitLeaseRequestDTO( customerId, slipId, duration ); + ISlip slip = _mockery.DynamicMock< ISlip >( ); + ICustomer customer = _mockery.DynamicMock< ICustomer >( ); + + using ( _mockery.Record( ) ) { + SetupResult.For( _customers.FindBy( customerId ) ).Return( customer ); + SetupResult.For( _slips.FindBy( slipId ) ).Return( slip ); + + customer.Lease( slip, LeaseDurations.FindBy( duration ) ); + } + + using ( _mockery.Playback( ) ) { + CreateSUT( ).RequestLeaseUsing( request ); + } + } + + [Test] + public void should_return_success_response_message() { + long customerId = 87; + long slipId = 32; + + string duration = LeaseDurations.Daily.Name( ); + + using ( _mockery.Record( ) ) { + SetupResult.For( _customers.FindBy( customerId ) ).Return( _mockery.DynamicMock< ICustomer >( ) ); + } + + using ( _mockery.Playback( ) ) { + DisplayResponseLineDTO response = + CreateSUT( ).RequestLeaseUsing( new SubmitLeaseRequestDTO( customerId, slipId, duration ) ); + Assert.AreEqual( response.Message, "Success!" ); + } + } + + [Test] + public void Should_return_error_message_if_the_slip_is_already_leased() { + ICustomer customer = _mockery.DynamicMock< ICustomer >( ); + using ( _mockery.Record( ) ) { + SetupResult + .For( _customers.FindBy( 0 ) ) + .IgnoreArguments( ) + .Return( customer ); + + customer.Lease( null, null ); + LastCall + .IgnoreArguments( ) + .Throw( new SlipIsAlreadyLeasedException( ) ); + } + + using ( _mockery.Playback( ) ) { + SubmitLeaseRequestDTO request = new SubmitLeaseRequestDTO( 1, 2, "weekly" ); + DisplayResponseLineDTO response = CreateSUT( ).RequestLeaseUsing( request ); + Assert.AreEqual( "Slip is already leased!", response.Message ); + } + } + + [Test] + public void Should_save_customer_back_to_repository() { + long customerId = 87; + long slipId = 32; + + ICustomer customer = _mockery.DynamicMock< ICustomer >( ); + + using ( _mockery.Record( ) ) { + SetupResult + .For( _customers.FindBy( customerId ) ) + .Return( customer ); + _customers.Save( customer ); + } + + using ( _mockery.Playback( ) ) { + CreateSUT( ).RequestLeaseUsing( new SubmitLeaseRequestDTO( customerId, slipId, LeaseDurations.Daily.Name( ) ) ); + } + } + } +} \ No newline at end of file diff --git a/slips/src/test/Marina.Test/Unit/Task/RegistrationTasksTest.cs b/slips/src/test/Marina.Test/Unit/Task/RegistrationTasksTest.cs new file mode 100644 index 0000000..226fae0 --- /dev/null +++ b/slips/src/test/Marina.Test/Unit/Task/RegistrationTasksTest.cs @@ -0,0 +1,217 @@ +using System; +using System.Collections.Generic; +using Marina.Domain.Interfaces; +using Marina.Domain.Repositories; +using Marina.Infrastructure; +using Marina.Presentation.DTO; +using Marina.Task; +using Marina.Task.Mappers; +using MbUnit.Framework; +using Rhino.Mocks; + +namespace Marina.Test.Unit.Task { + [TestFixture] + public class RegistrationTasksTest { + private MockRepository _mockery; + private ICustomerRepository _mockCustomerRepository; + private IBrokenRulesToDisplayItemMapper _mockMapper; + + [SetUp] + public void Setup() { + _mockery = new MockRepository( ); + _mockCustomerRepository = _mockery.DynamicMock< ICustomerRepository >( ); + _mockMapper = _mockery.DynamicMock< IBrokenRulesToDisplayItemMapper >( ); + } + + public IRegistrationTasks CreateSUT() { + return new RegistrationTasks( _mockMapper, _mockCustomerRepository ); + } + + [Test] + public void Should_leverage_repository_to_create_a_new_customer() { + string username = "username"; + string password = "password"; + string firstName = "mo"; + string lastName = "khan"; + string phoneNumber = "4036813389"; + string city = "calgary"; + RegisterCustomerDTO customerDTO = + new RegisterCustomerDTO( username, password, firstName, lastName, phoneNumber, city ); + + ICustomer customer = _mockery.DynamicMock< ICustomer >( ); + IRegistration registration = _mockery.DynamicMock< IRegistration >( ); + using ( _mockery.Record( ) ) { + SetupResult.For( customer.Registration( ) ).Return( registration ); + SetupResult.For( registration.IsValid( ) ).Return( true ); + + Expect.Call( _mockCustomerRepository.NewCustomer( ) ).Return( customer ); + customer.RegisterAccount( username, password, firstName, lastName, phoneNumber, city ); + } + + using ( _mockery.Playback( ) ) { + ListFactory.From( CreateSUT( ).RegisterNew( customerDTO ) ); + } + } + + private RegisterCustomerDTO RegisterCustomerDTO() { + string username = "username"; + string password = "password"; + string firstName = "mo"; + string lastName = "khan"; + string phoneNumber = "4036813389"; + string city = "calgary"; + return new RegisterCustomerDTO( username, password, firstName, lastName, phoneNumber, city ); + } + + [Test] + public void Should_return_registration_messages() { + IRegistration registration = _mockery.DynamicMock< IRegistration >( ); + ICustomer customer = _mockery.DynamicMock< ICustomer >( ); + + IList< DisplayResponseLineDTO > brokenRulesDtos = new List< DisplayResponseLineDTO >( ); + IList< IBrokenRule > brokenRules = new List< IBrokenRule >( ); + + using ( _mockery.Record( ) ) { + SetupResult.For( _mockCustomerRepository.NewCustomer( ) ).Return( customer ); + SetupResult.For( customer.Registration( ) ).Return( registration ); + + using ( _mockery.Ordered( ) ) { + Expect.Call( registration.IsValid( ) ).Return( false ); + Expect.Call( registration.BrokenRules( ) ).Return( brokenRules ); + Expect.Call( _mockMapper.MapFrom( brokenRules ) ).Return( brokenRulesDtos ); + } + } + + using ( _mockery.Playback( ) ) { + Assert.AreEqual( brokenRulesDtos, CreateSUT( ).RegisterNew( RegisterCustomerDTO( ) ) ); + } + } + + [Test] + public void Should_return_a_success_message_if_there_are_no_broken_rules() { + IRegistration registration = _mockery.CreateMock< IRegistration >( ); + + ICustomer customer = _mockery.DynamicMock< ICustomer >( ); + using ( _mockery.Record( ) ) { + Expect.Call( _mockCustomerRepository.NewCustomer( ) ).Return( customer ); + SetupResult.For( customer.Registration( ) ).Return( registration ); + Expect + .Call( registration.IsValid( ) ) + .Return( true ); + } + + using ( _mockery.Playback( ) ) { + IRichList< DisplayResponseLineDTO > lineItems = + ListFactory.From( CreateSUT( ).RegisterNew( RegisterCustomerDTO( ) ) ); + Assert.IsTrue( lineItems.Contains( new DisplayResponseLineDTO( "Success!" ) ) ); + } + } + + [Test] + public void Should_lookup_customer_from_repository_using_customer_id() { + int customerId = 1; + ICustomer customer = _mockery.DynamicMock< ICustomer >( ); + using ( _mockery.Record( ) ) { + Expect.Call( _mockCustomerRepository.FindBy( customerId ) ).Return( customer ); + } + + using ( _mockery.Playback( ) ) { + CreateSUT( ).AddNewBoatUsing( new BoatRegistrationDTO( "reg#", "YAMAHA", "2007", "100", customerId ) ); + } + } + + [Test] + public void Should_register_boat_with_customer() { + int customerId = 1; + ICustomer customer = _mockery.DynamicMock< ICustomer >( ); + using ( _mockery.Record( ) ) { + SetupResult.For( _mockCustomerRepository.FindBy( customerId ) ).Return( customer ); + customer.RegisterBoat( "reg#", "YAMAHA", new DateTime( 2007, 01, 01 ), 100 ); + } + + using ( _mockery.Playback( ) ) { + CreateSUT( ).AddNewBoatUsing( new BoatRegistrationDTO( "reg#", "YAMAHA", "2007", "100", customerId ) ); + } + } + + [Test] + public void Should_save_the_changed_customer_to_the_repository() { + int customerId = 1; + ICustomer customer = _mockery.DynamicMock< ICustomer >( ); + using ( _mockery.Record( ) ) { + using ( _mockery.Ordered( ) ) { + SetupResult.For( _mockCustomerRepository.FindBy( customerId ) ).Return( customer ); + customer.RegisterBoat( "reg#", "YAMAHA", new DateTime( 2007, 01, 01 ), 100 ); + _mockCustomerRepository.Save( customer ); + } + } + + using ( _mockery.Playback( ) ) { + CreateSUT( ).AddNewBoatUsing( new BoatRegistrationDTO( "reg#", "YAMAHA", "2007", "100", customerId ) ); + } + } + + [Test] + public void Should_leverage_repository_to_find_customer() { + int customerId = 1; + ICustomer customer = _mockery.DynamicMock< ICustomer >( ); + IRegistration registration = _mockery.DynamicMock< IRegistration >( ); + using ( _mockery.Record( ) ) { + SetupResult.For( registration.FirstName( ) ).Return( "mo" ); + SetupResult.For( registration.Username( ) ).Return( "mokhan" ); + SetupResult.For( registration.LastName( ) ).Return( "khan" ); + SetupResult.For( registration.PhoneNumber( ) ).Return( "4036813389" ); + SetupResult.For( registration.City( ) ).Return( "calgary" ); + + SetupResult.For( customer.Registration( ) ).Return( registration ); + Expect.Call( _mockCustomerRepository.FindBy( customerId ) ).Return( customer ); + } + + using ( _mockery.Playback( ) ) { + Assert.AreEqual( + new CustomerRegistrationDisplayDTO( "1", "mokhan", "mo", "khan", "4036813389", "calgary" ), + CreateSUT( ).LoadRegistrationFor( customerId ) ); + } + } + + [Test] + public void Should_leverage_repository_to_update_the_customer_information() { + int customerId = 1; + ICustomer customer = _mockery.DynamicMock< ICustomer >( ); + IRegistration registration = _mockery.DynamicMock< IRegistration >( ); + using ( _mockery.Record( ) ) { + SetupResult.For( customer.Registration( ) ).Return( registration ); + SetupResult.For( registration.IsValid( ) ).Return( true ); + + using ( _mockery.Ordered( ) ) { + Expect.Call( _mockCustomerRepository.FindBy( customerId ) ).Return( customer ); + customer.UpdateRegistrationTo( "mokhan", "password", "mo", "khan", "4036813389", "calgary" ); + _mockCustomerRepository.Save( customer ); + } + } + + using ( _mockery.Playback( ) ) { + CreateSUT( ).UpdateRegistrationFor( + new UpdateCustomerRegistrationDTO( 1, "mokhan", "password", "mo", "khan", "4036813389", "calgary" ) ); + } + } + + [Test] + public void Should_not_save_customer_if_registration_information_is_incorrect() { + int customerId = 1; + ICustomer customer = _mockery.DynamicMock< ICustomer >( ); + IRegistration registration = _mockery.DynamicMock< IRegistration >( ); + + using ( _mockery.Record( ) ) { + SetupResult.For( customer.Registration( ) ).Return( registration ); + SetupResult.For( registration.IsValid( ) ).Return( false ); + SetupResult.For( _mockCustomerRepository.FindBy( customerId ) ).Return( customer ); + } + + using ( _mockery.Playback( ) ) { + CreateSUT( ).UpdateRegistrationFor( + new UpdateCustomerRegistrationDTO( 1, "mokhan", "password", "mo", "khan", "4036813389", "calgary" ) ); + } + } + } +} \ No newline at end of file diff --git a/slips/src/test/Marina.Test/Unit/Web/Commands/AvailableSlipsCommandTest.cs b/slips/src/test/Marina.Test/Unit/Web/Commands/AvailableSlipsCommandTest.cs new file mode 100644 index 0000000..c3ca810 --- /dev/null +++ b/slips/src/test/Marina.Test/Unit/Web/Commands/AvailableSlipsCommandTest.cs @@ -0,0 +1,56 @@ +using System.Collections.Generic; +using Marina.Infrastructure; +using Marina.Presentation.DTO; +using Marina.Task; +using Marina.Web.Commands; +using Marina.Web.Views.Pages; +using MbUnit.Framework; +using Rhino.Mocks; + +namespace Marina.Test.Unit.Web.Commands { + [TestFixture] + public class AvailableSlipsCommandTest { + private MockRepository _mockery; + private ICatalogTasks _mockTask; + private IAvailableSlipsWebView _mockView; + + [SetUp] + public void Setup() { + _mockery = new MockRepository( ); + _mockTask = _mockery.DynamicMock< ICatalogTasks >( ); + _mockView = _mockery.DynamicMock< IAvailableSlipsWebView >( ); + } + + private ICommand CreateSUT() { + return new AvailableSlipsCommand( _mockView, _mockTask ); + } + + [Test] + public void Should_leverage_task_to_retrieve_all_available_slips_on_initialize() { + using ( _mockery.Record( ) ) { + Expect.Call( _mockTask.GetAllAvailableSlips( ) ).Return( null ); + } + + using ( _mockery.Playback( ) ) { + CreateSUT( ).Execute( ); + } + } + + [Test] + public void Should_add_available_slips_to_bag_and_render_view() { + IEnumerable< SlipDisplayDTO > slips = new List< SlipDisplayDTO >( ); + + using ( _mockery.Record( ) ) { + SetupResult.For( _mockTask.GetAllAvailableSlips( ) ).Return( slips ); + using ( _mockery.Ordered( ) ) { + _mockView.AddToBag( slips ); + _mockView.Render( ); + } + } + + using ( _mockery.Playback( ) ) { + CreateSUT( ).Execute( ); + } + } + } +} \ No newline at end of file diff --git a/slips/src/test/Marina.Test/Unit/Web/Handlers/RequestHandlerSpecificationTest.cs b/slips/src/test/Marina.Test/Unit/Web/Handlers/RequestHandlerSpecificationTest.cs new file mode 100644 index 0000000..8b6c4fd --- /dev/null +++ b/slips/src/test/Marina.Test/Unit/Web/Handlers/RequestHandlerSpecificationTest.cs @@ -0,0 +1,53 @@ +using Marina.Infrastructure; +using Marina.Web.Handlers; +using Marina.Web.Http; +using MbUnit.Framework; +using Rhino.Mocks; + +namespace Marina.Test.Unit.Web.Handlers { + [TestFixture] + public class RequestHandlerSpecificationTest { + private MockRepository _mockery; + + [SetUp] + public void Setup( ) { + _mockery = new MockRepository( ); + } + + [TearDown] + public void TearDown( ) { + _mockery.VerifyAll( ); + } + + [Test] + public void Should_return_true_if_destination_contains_command_name( ) { + IHttpGateway mockRequest = _mockery.DynamicMock< IHttpGateway >( ); + string commandName = "test.marina"; + using ( _mockery.Record( ) ) { + SetupResult.For( mockRequest.Destination( ) ).Return( commandName ); + } + + using ( _mockery.Playback( ) ) { + Assert.IsTrue( CreateSUT( commandName ).IsSatisfiedBy( mockRequest ) ); + } + } + + [Test] + public void Should_return_false_if_destination_does_not_contain_command_name( ) { + IHttpGateway mockRequest = _mockery.DynamicMock< IHttpGateway >( ); + string firstCommandName = "test.marina"; + string secondCommandName = "test2.marina"; + + using ( _mockery.Record( ) ) { + SetupResult.For( mockRequest.Destination( ) ).Return( secondCommandName ); + } + using ( _mockery.Playback( ) ) { + Assert.IsFalse( CreateSUT( firstCommandName ).IsSatisfiedBy( mockRequest ) ); + } + } + + private ISpecification< IHttpGateway > CreateSUT( string commandName ) { + return new RequestHandlerSpecification( commandName ); + } + } +} \ No newline at end of file diff --git a/slips/src/test/Marina.Test/Unit/Web/Handlers/RequestHandlerTest.cs b/slips/src/test/Marina.Test/Unit/Web/Handlers/RequestHandlerTest.cs new file mode 100644 index 0000000..b4a15ef --- /dev/null +++ b/slips/src/test/Marina.Test/Unit/Web/Handlers/RequestHandlerTest.cs @@ -0,0 +1,49 @@ +using Marina.Infrastructure; +using Marina.Web.Handlers; +using Marina.Web.Http; +using MbUnit.Framework; +using Rhino.Mocks; + +namespace Marina.Test.Unit.Web.Handlers { + [TestFixture] + public class RequestHandlerTest { + private MockRepository _mockery; + private ISpecification< IHttpGateway > _mockSpecification; + private ICommand _mockCommand; + + [SetUp] + public void Setup( ) { + _mockery = new MockRepository( ); + _mockSpecification = _mockery.DynamicMock< ISpecification< IHttpGateway > >( ); + _mockCommand = _mockery.DynamicMock< ICommand >( ); + } + + [Test] + public void Should_delegate_to_specification_to_see_if_criteria_is_satisfied( ) { + IHttpGateway request = _mockery.DynamicMock< IHttpGateway >( ); + + using ( _mockery.Record( ) ) { + Expect.Call( _mockSpecification.IsSatisfiedBy( request ) ).Return( true ); + } + + using ( _mockery.Playback( ) ) { + CreateSUT( ).IsSatisfiedBy( request ); + } + } + + [Test] + public void Should_delegate_to_command_when_told_to_execute( ) { + using ( _mockery.Record( ) ) { + _mockCommand.Execute( ); + } + + using ( _mockery.Playback( ) ) { + CreateSUT( ).Execute( ); + } + } + + private IRequestHandler CreateSUT( ) { + return new RequestHandler( _mockSpecification, _mockCommand ); + } + } +} \ No newline at end of file diff --git a/slips/src/test/Marina.Test/Unit/Web/Views/Pages/AvailableSlipsWebViewTest.cs b/slips/src/test/Marina.Test/Unit/Web/Views/Pages/AvailableSlipsWebViewTest.cs new file mode 100644 index 0000000..2a40745 --- /dev/null +++ b/slips/src/test/Marina.Test/Unit/Web/Views/Pages/AvailableSlipsWebViewTest.cs @@ -0,0 +1,49 @@ +using System.Collections.Generic; +using Marina.Presentation.DTO; +using Marina.Web.Http; +using Marina.Web.Views; +using Marina.Web.Views.Pages; +using MbUnit.Framework; +using Rhino.Mocks; + +namespace Marina.Test.Unit.Web.Views.Pages { + [TestFixture] + public class AvailableSlipsWebViewTest { + private MockRepository _mockery; + private IViewLuggageTransporter< IEnumerable< SlipDisplayDTO > > _mockViewBag; + private IHttpGateway _mockGateway; + + [SetUp] + public void Setup() { + _mockery = new MockRepository( ); + _mockViewBag = _mockery.DynamicMock< IViewLuggageTransporter< IEnumerable< SlipDisplayDTO > > >( ); + _mockGateway = _mockery.DynamicMock< IHttpGateway >( ); + } + + public IAvailableSlipsWebView CreateSUT() { + return new AvailableSlipsWebView( _mockViewBag, _mockGateway ); + } + + [Test] + public void Should_add_item_to_view_bag() { + IEnumerable< SlipDisplayDTO > slips = new List< SlipDisplayDTO >( ); + + using ( _mockery.Record( ) ) { + _mockViewBag.Add( slips ); + } + + using ( _mockery.Playback( ) ) { + CreateSUT( ).AddToBag( slips ); + } + } + + [Test] + public void Should_return_the_name_of_the_page() { + using ( _mockery.Record( ) ) {} + + using ( _mockery.Playback( ) ) { + Assert.AreEqual( "AvailableSlips.aspx", CreateSUT( ).Name( ) ); + } + } + } +} \ No newline at end of file diff --git a/slips/src/test/Marina.Test/Unit/Web/Views/ViewTest.cs b/slips/src/test/Marina.Test/Unit/Web/Views/ViewTest.cs new file mode 100644 index 0000000..a3b2d08 --- /dev/null +++ b/slips/src/test/Marina.Test/Unit/Web/Views/ViewTest.cs @@ -0,0 +1,48 @@ +using Marina.Web.Http; +using Marina.Web.Views; +using MbUnit.Framework; +using Rhino.Mocks; +using Rhino.Mocks.Constraints; + +namespace Marina.Test.Unit.Web.Views { + [TestFixture] + public class ViewTest { + private MockRepository _mockery; + private string _pageName; + private IHttpGateway _mockGateway; + + [SetUp] + public void Setup() { + _mockery = new MockRepository( ); + _mockGateway = _mockery.DynamicMock< IHttpGateway >( ); + _pageName = string.Empty; + } + + public IView CreateSUT() { + return new View( _pageName, _mockGateway ); + } + + [Test] + public void Should_return_the_name_of_the_page_it_was_created_with() { + _pageName = "TestPage.aspx"; + + using ( _mockery.Record( ) ) {} + + using ( _mockery.Playback( ) ) { + Assert.AreEqual( _pageName, CreateSUT( ).Name( ) ); + } + } + + [Test] + public void Should_redirect_to_page() { + using ( _mockery.Record( ) ) { + _mockGateway.RedirectTo( null ); + LastCall.Constraints( Is.NotNull( ) ); + } + + using ( _mockery.Playback( ) ) { + CreateSUT( ).Render( ); + } + } + } +} \ No newline at end of file diff --git a/slips/src/test/Marina.Test/Utility/ObjectMother.cs b/slips/src/test/Marina.Test/Utility/ObjectMother.cs new file mode 100644 index 0000000..d98bfd7 --- /dev/null +++ b/slips/src/test/Marina.Test/Utility/ObjectMother.cs @@ -0,0 +1,69 @@ +using System; +using System.Collections.Generic; +using Marina.Domain; +using Marina.Domain.Interfaces; +using Marina.Presentation.DTO; + +namespace Marina.Test.Utility { + public class ObjectMother { + public static RegisterCustomerDTO CustomerRegistrationDTO() { + return + new RegisterCustomerDTO( string.Empty, string.Empty, string.Empty, string.Empty, string.Empty, string.Empty ); + } + + public static IEnumerable< DisplayResponseLineDTO > EnumerableDisplayResponseLineDTO() { + return new List< DisplayResponseLineDTO >( ); + } + + public static DockDisplayDTO DockDisplayDTO() { + return new DockDisplayDTO( string.Empty, string.Empty, string.Empty, string.Empty ); + } + + public static CustomerRegistrationDisplayDTO DisplayCustomerRegistrationDTO() { + return + new CustomerRegistrationDisplayDTO( string.Empty, string.Empty, string.Empty, string.Empty, + string.Empty, string.Empty ); + } + + public static UpdateCustomerRegistrationDTO UpdateCustomerRegistrationDTO() { + return new UpdateCustomerRegistrationDTO( 0, string.Empty, string.Empty, string.Empty, string.Empty, string.Empty, + string.Empty ); + } + + public static BoatRegistrationDTO BoatRegistrationDTO() { + return new BoatRegistrationDTO( string.Empty, string.Empty, string.Empty, string.Empty, 0 ); + } + + public static LoginCredentialsDTO LoginCredentialsDTO() { + return new LoginCredentialsDTO( string.Empty, string.Empty ); + } + + public static SlipDisplayDTO SlipDisplayDTO() { + return new SlipDisplayDTO( "1", "dock a", "100", "100", "location a", "2" ); + } + + public static ILocation Location() { + return new Location( "location a" ); + } + + public static IBoat Boat() { + return new Boat( -1, string.Empty, string.Empty, DateTime.Now, 100 ); + } + + public static ISlip Slip() { + return new Slip( -1, null, 100, 100, false ); + } + + public static ICustomer Customer() { + return new Customer( ); + } + + public static IDock Dock() { + return new Dock( -1, "dock a", null, null ); + } + + public static DisplayResponseLineDTO DisplayResponseLineDTO() { + return new DisplayResponseLineDTO( string.Empty ); + } + } +} \ No newline at end of file diff --git a/slips/src/test/Marina.Test/Utility/RunInRealContainerAttribute.cs b/slips/src/test/Marina.Test/Utility/RunInRealContainerAttribute.cs new file mode 100644 index 0000000..d161100 --- /dev/null +++ b/slips/src/test/Marina.Test/Utility/RunInRealContainerAttribute.cs @@ -0,0 +1,14 @@ +using System; +using MbUnit.Core.Framework; +using MbUnit.Core.Invokers; + +namespace Marina.Test.Utility +{ + public class RunInRealContainerAttribute : DecoratorPatternAttribute + { + public override IRunInvoker GetInvoker( IRunInvoker wrapper ) + { + return new RunInRealContainerRunInvoker( wrapper ); + } + } +} \ No newline at end of file diff --git a/slips/src/test/Marina.Test/Utility/RunInRealContainerRunInvoker.cs b/slips/src/test/Marina.Test/Utility/RunInRealContainerRunInvoker.cs new file mode 100644 index 0000000..cea4049 --- /dev/null +++ b/slips/src/test/Marina.Test/Utility/RunInRealContainerRunInvoker.cs @@ -0,0 +1,18 @@ +using System.Collections; +using Marina.Infrastructure.Container; +using Marina.Task; +using MbUnit.Core.Invokers; + +namespace Marina.Test.Utility { + public class RunInRealContainerRunInvoker : DecoratorRunInvoker { + public RunInRealContainerRunInvoker( IRunInvoker invoker ) + : base( invoker ) {} + + public override object Execute( object o, IList args ) { + ApplicationStartupTask.ApplicationBegin( ); + object result = base.Invoker.Execute( o, args ); + Resolve.InitializeWith( null ); + return result; + } + } +} \ No newline at end of file -- cgit v1.2.3