Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 10 additions & 1 deletion Sources/DataTransferObjects/DTOs/DTOv2.swift
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,11 @@ public enum DTOv2 {
case website
}

public enum StartOfWeek: String, Codable, Hashable {
case sunday
case monday
}

/// If true, the app should display demo content instead of
public var showExampleData: Bool?

Expand All @@ -219,10 +224,14 @@ public enum DTOv2 {
/// How should the overview page for this application be layouted?
public var displayMode: DisplayMode?

public init(displayMode: DisplayMode? = nil, colorScheme: String? = nil, showExampleData: Bool? = nil) {
/// The start of week when filtering using weekly filters like 'This Week'.
public var startOfWeek: StartOfWeek?

public init(displayMode: DisplayMode? = nil, colorScheme: String? = nil, showExampleData: Bool? = nil, startOfWeek: StartOfWeek? = nil) {
self.displayMode = displayMode ?? .app
self.colorScheme = colorScheme
self.showExampleData = showExampleData ?? false
self.startOfWeek = startOfWeek ?? .sunday
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ public extension CustomQuery {
/// @warn Both precompile AND compileToRunnableQuery need to be run before a query can safely be handed to Druid!
///
/// @see precompile
func compileToRunnableQuery() throws -> CustomQuery {
func compileToRunnableQuery(startWeekOnMonday: Bool) throws -> CustomQuery {
guard compilationStatus == .precompiled else {
throw QueryGenerationError.compilationStatusError
}
Expand All @@ -61,7 +61,7 @@ public extension CustomQuery {

// Compile relative Time intervals
if let relativeIntervals = query.relativeIntervals {
query.intervals = relativeIntervals.map { QueryTimeInterval.from(relativeTimeInterval: $0) }
query.intervals = relativeIntervals.map { QueryTimeInterval.from(relativeTimeInterval: $0, startWeekOnMonday: startWeekOnMonday) }
}

guard query.intervals != nil, !query.intervals!.isEmpty else {
Expand Down
13 changes: 8 additions & 5 deletions Sources/DataTransferObjects/Query/RelativeTimeInterval.swift
Original file line number Diff line number Diff line change
Expand Up @@ -66,11 +66,14 @@ public struct RelativeDate: Codable, Hashable, Equatable {
}

public extension Date {
static func from(relativeDate: RelativeDate) -> Date {
static func from(relativeDate: RelativeDate, startWeekOnMonday: Bool) -> Date {
var date = Date()

var calendar = date.calendar
calendar.firstWeekday = startWeekOnMonday ? 2 : 1 // 1 is Sunday, 2 is Monday

let calendarComponent = relativeDate.component.calendarComponent
date = date.calendar.date(byAdding: calendarComponent, value: relativeDate.offset, to: date) ?? date
date = calendar.date(byAdding: calendarComponent, value: relativeDate.offset, to: date) ?? date

switch relativeDate.position {
case .beginning:
Expand All @@ -84,10 +87,10 @@ public extension Date {
}

public extension QueryTimeInterval {
static func from(relativeTimeInterval: RelativeTimeInterval) -> QueryTimeInterval {
static func from(relativeTimeInterval: RelativeTimeInterval, startWeekOnMonday: Bool) -> QueryTimeInterval {
QueryTimeInterval(
beginningDate: Date.from(relativeDate: relativeTimeInterval.beginningDate),
endDate: Date.from(relativeDate: relativeTimeInterval.endDate)
beginningDate: Date.from(relativeDate: relativeTimeInterval.beginningDate, startWeekOnMonday: startWeekOnMonday),
endDate: Date.from(relativeDate: relativeTimeInterval.endDate, startWeekOnMonday: startWeekOnMonday)
)
}
}
3 changes: 2 additions & 1 deletion Tests/DataTransferObjectsTests/EncodingDecodingTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ final class EncodingDecodingTests: XCTestCase {
let expectedOutput = """
{
"displayMode": "app",
"showExampleData": false
"showExampleData": false,
"startOfWeek": "sunday"
}
"""
.filter { !$0.isWhitespace }
Expand Down
10 changes: 5 additions & 5 deletions Tests/DataTransferObjectsTests/RelativeDateTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -134,26 +134,26 @@ final class RelativeDateTests: XCTestCase {
let beginningOfLastMonthRelative = RelativeDate(.beginning, of: .month, adding: -1)
let beginningOfLastMonthAbsolute = Date().calendar.date(byAdding: .month, value: -1, to: Date())!.beginning(of: .month)

XCTAssertEqual(beginningOfLastMonthAbsolute, Date.from(relativeDate: beginningOfLastMonthRelative))
XCTAssertEqual(beginningOfLastMonthAbsolute, Date.from(relativeDate: beginningOfLastMonthRelative, startWeekOnMonday: false))

let endOfThisMonthRelative = RelativeDate(.end, of: .month, adding: 0)
let endOfThisMonthAbsolute = Date().end(of: .month)

XCTAssertEqual(endOfThisMonthAbsolute, Date.from(relativeDate: endOfThisMonthRelative))
XCTAssertEqual(endOfThisMonthAbsolute, Date.from(relativeDate: endOfThisMonthRelative, startWeekOnMonday: false))

let beginningOfNextWeekRelative = RelativeDate(.beginning, of: .week, adding: 1)
let beginningOfNextWeekAbsolute = Date().calendar.date(byAdding: .weekOfYear, value: 1, to: Date())!.beginning(of: .weekOfYear)!

XCTAssertEqual(beginningOfNextWeekAbsolute, Date.from(relativeDate: beginningOfNextWeekRelative))
XCTAssertEqual(beginningOfNextWeekAbsolute, Date.from(relativeDate: beginningOfNextWeekRelative, startWeekOnMonday: false))

let endOfTodayRelative = RelativeDate(.end, of: .day, adding: 0)
let endOfTodayAbsolute = Date().end(of: .day)

XCTAssertEqual(endOfTodayAbsolute, Date.from(relativeDate: endOfTodayRelative))
XCTAssertEqual(endOfTodayAbsolute, Date.from(relativeDate: endOfTodayRelative, startWeekOnMonday: false))

let in30HoursRelative = RelativeDate(.beginning, of: .hour, adding: 30)
let in30HoursAbsolute = Date().startOfHour.adding(.hour, value: 30).startOfHour

XCTAssertEqual(in30HoursAbsolute, Date.from(relativeDate: in30HoursRelative))
XCTAssertEqual(in30HoursAbsolute, Date.from(relativeDate: in30HoursRelative, startWeekOnMonday: false))
}
}
20 changes: 10 additions & 10 deletions Tests/QueryGenerationTests/CompileDownTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -123,13 +123,13 @@ final class CompileDownTests: XCTestCase {

func testCompilationFailsIfNoPrecompilation() throws {
let query = CustomQuery(queryType: .timeseries, relativeIntervals: relativeIntervals, granularity: .all)
XCTAssertThrowsError(try query.compileToRunnableQuery())
XCTAssertThrowsError(try query.compileToRunnableQuery(startWeekOnMonday: false))
}

func testIntervalsAreCreated() throws {
let query = CustomQuery(queryType: .timeseries, relativeIntervals: relativeIntervals, granularity: .all)
let precompiledQuery = try query.precompile(organizationAppIDs: [appID1, appID2], isSuperOrg: false)
let compiledQuery = try precompiledQuery.compileToRunnableQuery()
let compiledQuery = try precompiledQuery.compileToRunnableQuery(startWeekOnMonday: false)

XCTAssertNotNil(compiledQuery.intervals)
XCTAssertFalse(compiledQuery.intervals!.isEmpty)
Expand All @@ -138,15 +138,15 @@ final class CompileDownTests: XCTestCase {
func testCompilationStatusIsSetCorrectly() throws {
let query = CustomQuery(queryType: .timeseries, relativeIntervals: relativeIntervals, granularity: .all)
let precompiledQuery = try query.precompile(organizationAppIDs: [appID1, appID2], isSuperOrg: false)
let compiledQuery = try precompiledQuery.compileToRunnableQuery()
let compiledQuery = try precompiledQuery.compileToRunnableQuery(startWeekOnMonday: false)

XCTAssertEqual(precompiledQuery.compilationStatus, .precompiled)
XCTAssertEqual(compiledQuery.compilationStatus, .compiled)
}

func testThrowsIfCompilationStatusNotSetCorrectly() throws {
let query = CustomQuery(queryType: .timeseries, relativeIntervals: relativeIntervals, granularity: .all)
XCTAssertThrowsError(try query.compileToRunnableQuery())
XCTAssertThrowsError(try query.compileToRunnableQuery(startWeekOnMonday: false))
}

func testRestrictions() throws {
Expand All @@ -167,7 +167,7 @@ final class CompileDownTests: XCTestCase {

let query = CustomQuery(queryType: .timeseries, restrictions: restrictions, intervals: intervals, granularity: .all)
let precompiledQuery = try query.precompile(organizationAppIDs: [appID1, appID2], isSuperOrg: false)
let compiledQuery = try precompiledQuery.compileToRunnableQuery()
let compiledQuery = try precompiledQuery.compileToRunnableQuery(startWeekOnMonday: false)

XCTAssertEqual(compiledQuery.restrictions, [
.init(beginningDate: Date(iso8601String: "2023-03-01T00:00:00.000Z")!, endDate: Date(iso8601String: "2023-04-02T00:00:00.000Z")!),
Expand All @@ -182,7 +182,7 @@ final class CompileDownTests: XCTestCase {

let query = CustomQuery(queryType: .timeseries, sampleFactor: 1, intervals: intervals, granularity: .day)
let precompiledQuery = try query.precompile(organizationAppIDs: [appID1, appID2], isSuperOrg: false)
let compiledQuery = try precompiledQuery.compileToRunnableQuery()
let compiledQuery = try precompiledQuery.compileToRunnableQuery(startWeekOnMonday: false)
XCTAssertEqual(compiledQuery.dataSource?.name, "telemetry-signals")
}

Expand All @@ -193,7 +193,7 @@ final class CompileDownTests: XCTestCase {

let query = CustomQuery(queryType: .timeseries, sampleFactor: 10, intervals: intervals, granularity: .day)
let precompiledQuery = try query.precompile(organizationAppIDs: [appID1, appID2], isSuperOrg: false)
let compiledQuery = try precompiledQuery.compileToRunnableQuery()
let compiledQuery = try precompiledQuery.compileToRunnableQuery(startWeekOnMonday: false)
XCTAssertEqual(compiledQuery.dataSource?.name, "telemetry-signals-sample10")
}

Expand All @@ -204,7 +204,7 @@ final class CompileDownTests: XCTestCase {

let query = CustomQuery(queryType: .timeseries, sampleFactor: 100, intervals: intervals, granularity: .day)
let precompiledQuery = try query.precompile(organizationAppIDs: [appID1, appID2], isSuperOrg: false)
let compiledQuery = try precompiledQuery.compileToRunnableQuery()
let compiledQuery = try precompiledQuery.compileToRunnableQuery(startWeekOnMonday: false)
XCTAssertEqual(compiledQuery.dataSource?.name, "telemetry-signals-sample100")
}

Expand All @@ -215,7 +215,7 @@ final class CompileDownTests: XCTestCase {

let query = CustomQuery(queryType: .timeseries, sampleFactor: 1000, intervals: intervals, granularity: .day)
let precompiledQuery = try query.precompile(organizationAppIDs: [appID1, appID2], isSuperOrg: false)
let compiledQuery = try precompiledQuery.compileToRunnableQuery()
let compiledQuery = try precompiledQuery.compileToRunnableQuery(startWeekOnMonday: false)
XCTAssertEqual(compiledQuery.dataSource?.name, "telemetry-signals-sample1000")
}

Expand All @@ -226,7 +226,7 @@ final class CompileDownTests: XCTestCase {

let query = CustomQuery(queryType: .timeseries, sampleFactor: 42, intervals: intervals, granularity: .day)
let precompiledQuery = try query.precompile(organizationAppIDs: [appID1, appID2], isSuperOrg: false)
let compiledQuery = try precompiledQuery.compileToRunnableQuery()
let compiledQuery = try precompiledQuery.compileToRunnableQuery(startWeekOnMonday: false)
XCTAssertEqual(compiledQuery.dataSource?.name, "telemetry-signals")
}
}