示例#1
0
            public void CorrectlyIdentifiesNonMatchingIds(IThreadSafeTimeEntry timeEntryA, IThreadSafeTimeEntry timeEntryB)
            {
                var groupA = new GroupId(timeEntryA);
                var groupB = new GroupId(timeEntryB);

                groupA.Equals(groupB).Should().BeFalse();
            }
示例#2
0
        private CalendarItem(IThreadSafeTimeEntry timeEntry)
            : this(
                timeEntry.Id.ToString(),
                CalendarItemSource.TimeEntry,
                timeEntry.Start,
                timeEntry.Duration.HasValue ? TimeSpan.FromSeconds(timeEntry.Duration.Value) : null as TimeSpan?,
                timeEntry.Description,
                CalendarIconKind.None,
                timeEntry.Project?.Color ?? ColorHelper.NoProject,
                timeEntry.Id)
        {
            switch (timeEntry.SyncStatus)
            {
            case SyncStatus.SyncNeeded:
                IconKind = CalendarIconKind.Unsynced;
                break;

            case SyncStatus.SyncFailed:
                IconKind = CalendarIconKind.Unsyncable;
                break;

            default:
                break;
            }
        }
示例#3
0
 private void notifyTimeEntryDeleted(IThreadSafeTimeEntry timeEntry)
 {
     if (dataSource is TimeEntriesDataSource timeEntriesDataSource)
     {
         timeEntriesDataSource.OnTimeEntrySoftDeleted(timeEntry);
     }
 }
 private static IEnumerable <LogItemViewModel> single(IThreadSafeTimeEntry timeEntry, DurationFormat durationFormat)
 {
     yield return(timeEntry.ToViewModel(
                      new GroupId(timeEntry),
                      LogItemVisualizationIntent.SingleItem,
                      durationFormat));
 }
示例#5
0
 public static LogItemViewModel ToViewModel(
     this IThreadSafeTimeEntry timeEntry,
     GroupId groupId,
     LogItemVisualizationIntent visualizationIntent,
     DurationFormat durationFormat,
     int indexInLog,
     int dayInLog,
     int daysInThePast)
 => new LogItemViewModel(
     groupId,
     new[] { timeEntry.Id },
     visualizationIntent,
     timeEntry.Billable,
     timeEntry.Description,
     timeEntry.Duration.HasValue
             ? DurationAndFormatToString.Convert(
         TimeSpan.FromSeconds(timeEntry.Duration.Value), durationFormat)
             : string.Empty,
     timeEntry.Project?.DisplayName(),
     timeEntry.Project?.DisplayColor(),
     timeEntry.Project?.Client?.Name,
     timeEntry.Task?.Name,
     timeEntry.TagIds.Any(),
     timeEntry.SyncStatus == SyncStatus.SyncNeeded,
     timeEntry.SyncStatus != SyncStatus.SyncFailed,
     timeEntry.IsInaccessible,
     indexInLog,
     dayInLog,
     daysInThePast);
        private static void updateRunningNotification(IThreadSafeTimeEntry timeEntryViewModel, Activity activity, NotificationManager notificationManager)
        {
            if (notificationManager == null)
            {
                return;
            }

            if (timeEntryViewModel != null)
            {
                var startTime            = timeEntryViewModel.Start.ToUnixTimeMilliseconds();
                var timeEntryDescription = string.IsNullOrEmpty(timeEntryViewModel.Description)
                    ? Resources.NoDescription
                    : timeEntryViewModel.Description;
                var projectDetails = extractProjectDetails(timeEntryViewModel);

                var notification = activity.CreateNotificationBuilderWithDefaultChannel(notificationManager)
                                   .SetShowWhen(true)
                                   .SetUsesChronometer(true)
                                   .SetAutoCancel(false)
                                   .SetOngoing(true)
                                   .SetContentTitle(timeEntryDescription)
                                   .SetContentText(projectDetails)
                                   .SetWhen(startTime)
                                   .SetContentIntent(getIntentFor(activity))
                                   .SetSmallIcon(Resource.Drawable.ic_icon_running)
                                   .Build();

                notificationManager.Notify(runningTimeEntryNotificationId, notification);
            }
            else
            {
                notificationManager.Cancel(runningTimeEntryNotificationId);
            }
        }
示例#7
0
        public TimeEntrySuggestion(IThreadSafeTimeEntry timeEntry)
        {
            Description   = timeEntry.Description;
            WorkspaceId   = timeEntry.WorkspaceId;
            WorkspaceName = timeEntry.Workspace?.Name ?? "";

            if (timeEntry.Project == null)
            {
                return;
            }
            HasProject   = true;
            ProjectId    = timeEntry.Project.Id;
            ProjectName  = timeEntry.Project.DisplayName();
            ProjectColor = timeEntry.Project.DisplayColor();

            if (timeEntry.Project.Client != null)
            {
                ClientName = timeEntry.Project.Client.Name;
            }

            if (timeEntry.Task != null)
            {
                TaskId   = timeEntry.Task.Id;
                TaskName = timeEntry.Task.Name;
            }
        }
        public void DonateStartTimeEntry(IThreadSafeTimeEntry timeEntry)
        {
            if (!UIDevice.CurrentDevice.CheckSystemVersion(12, 0))
            {
                return;
            }

            var relevantShortcuts = new List <INRelevantShortcut>();

            var startTimerIntent = new StartTimerIntent();

            startTimerIntent.Workspace = new INObject(timeEntry.Workspace.Id.ToString(), timeEntry.Workspace.Name);

            if (!string.IsNullOrEmpty(timeEntry.Description))
            {
                // If any of the tags or the project id were just created and haven't sync we ignore this action until the user repeats it
                if (timeEntry.ProjectId < 0 || timeEntry.TagIds.Any(tagId => tagId < 0))
                {
                    return;
                }

                if (timeEntry.ProjectId is long projectId)
                {
                    var projectINObject = new INObject(timeEntry.ProjectId.ToString(), timeEntry.Project.Name);
                    startTimerIntent.ProjectId = projectINObject;
                }

                startTimerIntent.EntryDescription = timeEntry.Description;

                var tags = timeEntry.TagIds.Select(tag => new INObject(tag.ToString(), tag.ToString())).ToArray();
                startTimerIntent.Tags = tags;

                var billable = new INObject(timeEntry.Billable.ToString(), timeEntry.Billable.ToString());
                startTimerIntent.Billable = billable;
                startTimerIntent.SuggestedInvocationPhrase = string.Format(Resources.SiriTrackEntrySuggestedInvocationPhrase, timeEntry.Description);


                // Relevant shortcut for the Siri Watch Face
                relevantShortcuts.Add(createRelevantShortcut(startTimerIntent));
            }
            else
            {
                startTimerIntent.SuggestedInvocationPhrase = Resources.StartTimerInvocationPhrase;
            }

            var startTimerInteraction = new INInteraction(startTimerIntent, null);

            startTimerInteraction.DonateInteraction(trackError);

            // Descriptionless Relevant Shortcut. Always added even if the intent has one
            var descriptionlessIntent = new StartTimerIntent();

            descriptionlessIntent.Workspace = new INObject(timeEntry.Workspace.Id.ToString(), timeEntry.Workspace.Name);
            var descriptionlessShortcut = createRelevantShortcut(descriptionlessIntent);

            relevantShortcuts.Add(descriptionlessShortcut);

            donateRelevantShortcuts(relevantShortcuts.ToArray());
        }
示例#9
0
        public ISpannable CreateProjectClientTaskLabel(IThreadSafeTimeEntry te)
        {
            if (te == null)
                return new SpannableString(string.Empty);

            var hasProject = te.ProjectId != null;
            return Extensions.TimeEntryExtensions.ToProjectTaskClient(hasProject, te.Project?.Name, te.Project?.Color, te.Task?.Name, te.Project?.Client?.Name);
        }
 private static LogItemViewModel groupItem(IThreadSafeTimeEntry timeEntry, DurationFormat durationFormat)
 => timeEntry.ToViewModel(
     new GroupId(timeEntry),
     LogItemVisualizationIntent.GroupItem,
     durationFormat,
     0,
     0,
     0);
示例#11
0
        private void insertNewTimeEntryGroup(IThreadSafeTimeEntry timeEntry, DateTime indexDate)
        {
            var timeEntryToAdd = new TimeEntryViewModel(timeEntry, durationFormat);
            var newCollection  = new TimeEntryViewModelCollection(indexDate, new[] { timeEntryToAdd }, durationFormat);
            var foundIndex     = TimeEntries.IndexOf(TimeEntries.FirstOrDefault(x => x.Date < indexDate));
            var indexToInsert  = foundIndex == -1 ? TimeEntries.Count : foundIndex;

            TimeEntries.Insert(indexToInsert, newCollection);
        }
示例#12
0
 public GroupId(IThreadSafeTimeEntry sample)
 {
     date        = sample.Start.LocalDateTime.Date;
     description = sample.Description;
     workspaceId = sample.WorkspaceId;
     projectId   = sample.Project?.Id;
     taskId      = sample.Task?.Id;
     isBillable  = sample.Billable;
     tagIds      = new HashSet <long>(sample.TagIds ?? Array.Empty <long>());
 }
示例#13
0
 public static ITimeEntryPrototype AsTimeEntryPrototype(this IThreadSafeTimeEntry timeEntry)
 => new TimeEntryPrototype(
     timeEntry.WorkspaceId,
     timeEntry.Description,
     TimeSpan.FromSeconds(timeEntry.Duration ?? 0.0),
     timeEntry.Start,
     timeEntry.Project?.Id,
     timeEntry.Task?.Id,
     timeEntry.TagIds.ToArray(),
     timeEntry.Billable);
        public NSAttributedString Convert(IThreadSafeTimeEntry timeEntry)
        {
            var projectColor = new Color(timeEntry.Project?.Color ?? string.Empty).ToNativeColor();

            return(Convert(
                       timeEntry.Project?.Name ?? "",
                       timeEntry.Task?.Name ?? "",
                       timeEntry.Project?.Client?.Name ?? "",
                       projectColor,
                       timeEntry.Project?.IsPlaceholder() ?? false,
                       timeEntry.Task?.IsPlaceholder() ?? false));
        }
示例#15
0
 private EditTimeEntryDto createDto(IThreadSafeTimeEntry timeEntry)
 {
     return(new EditTimeEntryDto
     {
         Id = timeEntry.Id,
         Description = timeEntry.Description + " Updated",
         StartTime = DateTimeOffset.UtcNow,
         ProjectId = 13,
         Billable = true,
         WorkspaceId = 71,
         TagIds = new long[] { 1, 10, 34, 42 }
     });
 }
示例#16
0
        private static NSAttributedString getFormattedProjectInfo(
            IThreadSafeTimeEntry timeEntry,
            UIColor projectColor,
            UIColor clientColor)
        {
            var builder   = new StringBuilder();
            var hasClient = !string.IsNullOrEmpty(timeEntry.Project.Client?.Name);

            if (!string.IsNullOrEmpty(timeEntry.Project.Name))
            {
                builder.Append($" {timeEntry.Project.Name}");
            }

            if (!string.IsNullOrEmpty(timeEntry.Task?.Name))
            {
                builder.Append($": {timeEntry.Task?.Name}");
            }

            if (hasClient)
            {
                builder.Append($" {timeEntry.Project.Client?.Name}");
            }

            var text = builder.ToString();

            var result      = new NSMutableAttributedString(text);
            var clientIndex = text.Length - (timeEntry.Project?.Client?.Name.Length ?? 0);

            if (projectColor != null)
            {
                var projectNameRange      = new NSRange(0, clientIndex);
                var projectNameAttributes = new UIStringAttributes {
                    ForegroundColor = projectColor
                };
                result.AddAttributes(projectNameAttributes, projectNameRange);
            }

            if (!hasClient)
            {
                return(result);
            }

            var clientNameRange      = new NSRange(clientIndex, timeEntry.Project.Client.Name.Length);
            var clientNameAttributes = new UIStringAttributes {
                ForegroundColor = clientColor
            };

            result.AddAttributes(clientNameAttributes, clientNameRange);

            return(result);
        }
示例#17
0
        public static void Save(IThreadSafeTimeEntry timeEntry)
        {
            var sharedPreferences = Application.Context.GetSharedPreferences(WidgetInfoSharedPreferencesName, FileCreationMode.Private);
            var editor            = sharedPreferences.Edit();

            editor.PutBoolean(IsRunningKey, timeEntry?.IsRunning() ?? false);
            editor.PutLong(StartTimeKey, timeEntry?.Start.ToUnixTimeSeconds() ?? default);
            editor.PutString(DescriptionKey, timeEntry?.Description ?? "");
            editor.PutBoolean(HasProjectKey, timeEntry?.ProjectId.HasValue ?? false);
            editor.PutString(ProjectNameKey, timeEntry?.Project?.Name ?? "");
            editor.PutString(ProjectColorKey, timeEntry?.Project?.Color ?? "");
            editor.PutBoolean(HasClientKey, timeEntry?.Project?.ClientId.HasValue ?? false);
            editor.PutString(ClientNameKey, timeEntry?.Project?.Client?.Name ?? "");
            editor.Apply();
        }
示例#18
0
 public MockTimeEntry(IThreadSafeTimeEntry entity)
 {
     Id              = entity.Id;
     WorkspaceId     = entity.WorkspaceId;
     ProjectId       = entity.ProjectId;
     TaskId          = entity.TaskId;
     Billable        = entity.Billable;
     Start           = entity.Start;
     Duration        = entity.Duration;
     Description     = entity.Description;
     TagIds          = entity.TagIds;
     At              = entity.At;
     ServerDeletedAt = entity.ServerDeletedAt;
     UserId          = entity.UserId;
 }
示例#19
0
        protected override void OnRunningTimeEntryChanged(IThreadSafeTimeEntry timeEntry)
        {
            if (timeEntry == null)
            {
                SharedStorage.Instance.SetRunningTimeEntry(null);
                return;
            }

            SharedStorage.Instance.SetRunningTimeEntry(
                timeEntry,
                timeEntry.Project?.Name ?? "",
                timeEntry.Project?.Color ?? "",
                timeEntry.Task?.Name ?? "",
                timeEntry.Project?.Client?.Name ?? "");
        }
示例#20
0
        private void safeInsertTimeEntry(IThreadSafeTimeEntry timeEntry)
        {
            var indexDate       = timeEntry.Start.LocalDateTime.Date;
            var collectionIndex = TimeEntries.IndexOf(x => x.Date.LocalDateTime == indexDate);
            var groupExists     = collectionIndex >= 0;

            if (groupExists)
            {
                insertTimeEntryInGroup(timeEntry, collectionIndex);
            }
            else
            {
                insertNewTimeEntryGroup(timeEntry, indexDate);
            }

            RaisePropertyChanged(nameof(IsEmpty));
        }
示例#21
0
        public override async Task Initialize(long[] timeEntryIds)
        {
            await base.Initialize(timeEntryIds);

            if (timeEntryIds == null || timeEntryIds.Length == 0)
            {
                throw new ArgumentException("Edit view has no Time Entries to edit.");
            }

            TimeEntryIds = timeEntryIds;

            var timeEntries = await interactorFactory.GetMultipleTimeEntriesById(TimeEntryIds).Execute();

            var timeEntry = timeEntries.First();

            originalTimeEntry = timeEntry;

            projectId = timeEntry.Project?.Id;
            taskId    = timeEntry.Task?.Id;
            workspaceIdSubject.OnNext(timeEntry.WorkspaceId);

            Description.Accept(timeEntry.Description);

            projectClientTaskSubject.OnNext(new ProjectClientTaskInfo(
                                                timeEntry.Project?.DisplayName(),
                                                timeEntry.Project?.DisplayColor(),
                                                timeEntry.Project?.Client?.Name,
                                                timeEntry.Task?.Name,
                                                timeEntry.Project?.IsPlaceholder() ?? false,
                                                timeEntry.Task?.IsPlaceholder() ?? false));

            isBillableSubject.OnNext(timeEntry.Billable);

            startTimeSubject.OnNext(timeEntry.Start);

            durationSubject.OnNext(timeEntry.TimeSpanDuration());

            GroupDuration = timeEntries.Sum(entry => entry.TimeSpanDuration());

            tagsSubject.OnNext(timeEntry.Tags?.ToImmutableList() ?? ImmutableList <IThreadSafeTag> .Empty);

            isInaccessibleSubject.OnNext(timeEntry.IsInaccessible);

            setupSyncError(timeEntries);
        }
示例#22
0
        private void setRunningEntry(IThreadSafeTimeEntry timeEntry)
        {
            CurrentTimeEntryId          = timeEntry?.Id;
            currentTimeEntryStart       = timeEntry?.Start;
            CurrentTimeEntryDescription = timeEntry?.Description ?? "";
            CurrentTimeEntryElapsedTime = timeService.CurrentDateTime - currentTimeEntryStart ?? TimeSpan.Zero;

            CurrentTimeEntryTask         = timeEntry?.Task?.Name ?? "";
            CurrentTimeEntryProject      = timeEntry?.Project?.DisplayName() ?? "";
            CurrentTimeEntryProjectColor = timeEntry?.Project?.DisplayColor() ?? "";
            CurrentTimeEntryClient       = timeEntry?.Project?.Client?.Name ?? "";

            isStopButtonEnabled = timeEntry != null;

            StopTimeEntryCommand.RaiseCanExecuteChanged();
            StartTimeEntryCommand.RaiseCanExecuteChanged();
            EditTimeEntryCommand.RaiseCanExecuteChanged();

            RaisePropertyChanged(nameof(IsTimeEntryRunning));
        }
        private static string extractProjectDetails(IThreadSafeTimeEntry timeEntryViewModel)
        {
            if (timeEntryViewModel.ProjectId == null)
            {
                return(Resources.NoProject);
            }

            var projectDetails = new StringBuilder(timeEntryViewModel.Project.Name);

            if (timeEntryViewModel.TaskId != null)
            {
                projectDetails.Append($": {timeEntryViewModel.Task.Name}");
            }

            if (timeEntryViewModel.Project.ClientId != null)
            {
                projectDetails.Append($" {dotSeparator} {timeEntryViewModel.Project.Client.Name}");
            }
            return(projectDetails.ToString());
        }
示例#24
0
        private string createAccessibilityLabelForRunningEntryCard(IThreadSafeTimeEntry timeEntry)
        {
            if (timeEntry == null)
            {
                return(null);
            }

            var accessibilityLabel = Resources.CurrentlyRunningTimeEntry;

            var duration = IosDependencyContainer.Instance.TimeService.CurrentDateTime - timeEntry.Start;

            accessibilityLabel += $", {duration}";

            if (!string.IsNullOrEmpty(timeEntry.Description))
            {
                accessibilityLabel += $", {timeEntry.Description}";
            }

            var projectName = timeEntry.Project?.Name ?? "";

            if (!string.IsNullOrEmpty(projectName))
            {
                accessibilityLabel += $", {Resources.Project}: {projectName}";
            }

            var taskName = timeEntry.Task?.Name ?? "";

            if (!string.IsNullOrEmpty(taskName))
            {
                accessibilityLabel += $", {Resources.Task}: {taskName}";
            }

            var clientName = timeEntry.Project?.Client?.Name ?? "";

            if (!string.IsNullOrEmpty(clientName))
            {
                accessibilityLabel += $", {Resources.Client}: {clientName}";
            }

            return(accessibilityLabel);
        }
示例#25
0
        public TimeEntryViewModel(IThreadSafeTimeEntry timeEntry, DurationFormat durationFormat)
        {
            Ensure.Argument.IsNotNull(timeEntry, nameof(timeEntry));

            if (timeEntry.IsRunning())
            {
                throw new InvalidOperationException("It is not possible to show a running time entry in the log.");
            }

            DurationFormat = durationFormat;

            Id             = timeEntry.Id;
            WorkspaceId    = timeEntry.WorkspaceId;
            StartTime      = timeEntry.Start;
            IsBillable     = timeEntry.Billable;
            TagIds         = timeEntry.TagIds.ToArray();
            HasTags        = TagIds.Count() > 0;
            Description    = timeEntry.Description;
            HasProject     = timeEntry.Project != null;
            Duration       = TimeSpan.FromSeconds(timeEntry.Duration.Value);
            HasDescription = !string.IsNullOrEmpty(timeEntry.Description);

            CanSync   = timeEntry.SyncStatus != SyncStatus.SyncFailed;
            NeedsSync = timeEntry.SyncStatus == SyncStatus.SyncNeeded;

            IsGhost = timeEntry.IsGhost;

            if (!HasProject)
            {
                return;
            }

            ProjectId    = timeEntry.Project.Id;
            ProjectName  = timeEntry.Project.DisplayName();
            ProjectColor = timeEntry.Project.DisplayColor();

            TaskId   = timeEntry.TaskId;
            TaskName = timeEntry.Task?.Name ?? "";

            ClientName = timeEntry.Project.Client?.Name ?? "";
        }
示例#26
0
        public static NSAttributedString ToFormattedTimeEntryString(
            this IThreadSafeTimeEntry timeEntry,
            nfloat fontHeight,
            UIColor clientColor,
            bool shouldColorProject)
        {
            if (string.IsNullOrEmpty(timeEntry.Project?.Name))
                return new NSAttributedString("");

            var displayColor = timeEntry.Project.DisplayColor();
            var color = string.IsNullOrEmpty(displayColor) ? null
                      : new Color(displayColor).ToNativeColor();

            var projectColor = shouldColorProject ? color : null;

            var result = getColoredDot(color, fontHeight);
            var projectInfo = getFormattedProjectInfo(timeEntry, projectColor, clientColor);
            result.Append(projectInfo);

            return result;
        }
示例#27
0
        public override async Task Initialize()
        {
            stopwatchFromCalendar = stopwatchProvider.Get(MeasuredOperation.EditTimeEntryFromCalendar);
            stopwatchProvider.Remove(MeasuredOperation.EditTimeEntryFromCalendar);
            stopwatchFromMainLog = stopwatchProvider.Get(MeasuredOperation.EditTimeEntryFromMainLog);
            stopwatchProvider.Remove(MeasuredOperation.EditTimeEntryFromMainLog);

            var timeEntries = await interactorFactory.GetMultipleTimeEntriesById(TimeEntryIds).Execute();

            var timeEntry = timeEntries.First();

            originalTimeEntry = timeEntry;

            projectId = timeEntry.Project?.Id;
            taskId    = timeEntry.Task?.Id;
            workspaceIdSubject.OnNext(timeEntry.WorkspaceId);

            Description.Accept(timeEntry.Description);

            projectClientTaskSubject.OnNext(new ProjectClientTaskInfo(
                                                timeEntry.Project?.DisplayName(),
                                                timeEntry.Project?.DisplayColor(),
                                                timeEntry.Project?.Client?.Name,
                                                timeEntry.Task?.Name));

            isBillableSubject.OnNext(timeEntry.Billable);

            startTimeSubject.OnNext(timeEntry.Start);

            durationSubject.OnNext(timeEntry.TimeSpanDuration());

            GroupDuration = timeEntries.Sum(entry => entry.TimeSpanDuration());

            tagsSubject.OnNext(timeEntry.Tags?.ToImmutableList() ?? ImmutableList <IThreadSafeTag> .Empty);

            isInaccessibleSubject.OnNext(timeEntry.IsInaccessible);

            setupSyncError(timeEntries);
        }
示例#28
0
        public ISpannable CreateProjectClientTaskLabel(IThreadSafeTimeEntry te)
        {
            if (te == null)
            {
                return(new SpannableString(string.Empty));
            }

            var hasProject           = te.ProjectId != null;
            var projectIsPlaceholder = te.Project?.IsPlaceholder() ?? false;
            var taskIsPlaceholder    = te.Task?.IsPlaceholder() ?? false;

            return(Extensions.TimeEntryExtensions.ToProjectTaskClient(
                       Context,
                       hasProject,
                       te.Project?.Name,
                       te.Project?.Color,
                       te.Task?.Name,
                       te.Project?.Client?.Name,
                       projectIsPlaceholder,
                       taskIsPlaceholder,
                       displayPlaceholders: true));
        }
示例#29
0
        public async Task DeleteProjectsUnreferencedByTasksInInaccessibleWorkspace()
        {
            var accessibleWorkspace   = new MockWorkspace(1000, isInaccessible: false);
            var inaccessibleWorkspace = new MockWorkspace(2000, isInaccessible: true);

            var project1 = new MockProject(101, accessibleWorkspace, syncStatus: SyncStatus.InSync);
            var project2 = new MockProject(102, accessibleWorkspace, syncStatus: SyncStatus.RefetchingNeeded);
            var project3 = new MockProject(201, inaccessibleWorkspace, syncStatus: SyncStatus.InSync);
            var project4 = new MockProject(202, inaccessibleWorkspace, syncStatus: SyncStatus.SyncNeeded);
            var project5 = new MockProject(203, inaccessibleWorkspace, syncStatus: SyncStatus.SyncNeeded);
            var project6 = new MockProject(204, inaccessibleWorkspace, syncStatus: SyncStatus.InSync);
            var project7 = new MockProject(205, inaccessibleWorkspace, syncStatus: SyncStatus.InSync);

            var task1 = new MockTask(1001, accessibleWorkspace, project1, SyncStatus.InSync);
            var task2 = new MockTask(1002, accessibleWorkspace, project2, SyncStatus.RefetchingNeeded);
            var task3 = new MockTask(1003, accessibleWorkspace, project2, SyncStatus.SyncNeeded);
            var task4 = new MockTask(2001, inaccessibleWorkspace, project3, SyncStatus.InSync);
            var task5 = new MockTask(2002, inaccessibleWorkspace, project4, SyncStatus.RefetchingNeeded);
            var task6 = new MockTask(2003, inaccessibleWorkspace, project3, SyncStatus.SyncNeeded);
            var task7 = new MockTask(2004, inaccessibleWorkspace, project4, SyncStatus.InSync);
            var task8 = new MockTask(2005, inaccessibleWorkspace, project4, SyncStatus.InSync);

            var projects    = new[] { project1, project2, project3, project4, project5, project6, project7 };
            var tasks       = new[] { task1, task2, task3, task4, task5, task6, task7, task8 };
            var timeEntries = new IThreadSafeTimeEntry[] { };

            var unreferencedProjects = new[] { project6, project7 };
            var neededProjects       = projects.Where(project => !unreferencedProjects.Contains(project));

            configureDataSource(projects, tasks, timeEntries);

            await state.Start().SingleAsync();

            projectsDataSource.Received().DeleteAll(Arg.Is <IEnumerable <IThreadSafeProject> >(arg =>
                                                                                               arg.All(project => unreferencedProjects.Contains(project)) &&
                                                                                               arg.None(project => neededProjects.Contains(project))));
        }
示例#30
0
 private bool isNotDeleted(IThreadSafeTimeEntry timeEntry)
 => !hiddenTimeEntries.Contains(timeEntry.Id);