Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[stable 4.9.7] Privacy Policy #145

Closed
wants to merge 4 commits into from
Closed
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
154 changes: 154 additions & 0 deletions Tests/NextcloudUnitTests/PrivacyPolicyTest.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
//
// PrivacyPolicyTest.swift
// NextcloudTests
//
// Created by A200073704 on 27/04/23.
// Copyright © 2023 Marino Faggiana. All rights reserved.
//

@testable import Nextcloud
import XCTest
import NextcloudKit
import XLForm


class PrivacyPolicyTest: XCTestCase {

var viewController: InitialPrivacySettingsViewController?
var privacySettingsView = PrivacySettingsViewController()

override func setUpWithError() throws {

// To Create an instance of UIStoryboard
let storyboard = UIStoryboard(name: "NCSettings", bundle: nil)

// To Instantiate UIViewController with Storyboard ID
viewController = storyboard.instantiateViewController(withIdentifier: "privacyPolicyViewController") as? InitialPrivacySettingsViewController

// Outlets are connected
let _ = viewController?.view

// Make the viewDidLoad() execute.
viewController?.loadViewIfNeeded()

}

override func tearDownWithError() throws {
viewController = nil
}

func testPrivacyPolicyViewControllerIsOpen() {

// Check that the InitialPrivacyPolicyViewController gets opened
let storyboard = UIStoryboard(name: "NCSettings", bundle: nil)
if let privacyPolicyViewController = storyboard.instantiateViewController(withIdentifier: "privacyPolicyViewController") as? InitialPrivacySettingsViewController {
let navigationController = UINavigationController(rootViewController: privacyPolicyViewController)

privacyPolicyViewController.loadViewIfNeeded()

XCTAssertTrue(navigationController.topViewController is InitialPrivacySettingsViewController, "Privacy policy view controller should be open")
}
}

func testTextViewHasCorrectText() {

//Check that the text displayed is correct
let expectedText = NSLocalizedString("_privacy_help_text_after_login_", comment: "")
viewController?.privacySettingsHelpText?.text = expectedText

let actualText = viewController?.privacySettingsHelpText?.text
XCTAssertEqual(actualText, expectedText, "The text view does not have the expected text")
}

func testHasAcceptButton() {

// Check that view has the accept button
let acceptButton = viewController?.acceptButton

XCTAssertNotNil(acceptButton, "View controller does not have an accept button")

}

func testSettingsLinkTypeNavigatesToPrivacySettingsViewController() {

// Simulate tapping the "Settings" link type
let linkType = LinkType.settings

UserDefaults.standard.set(true, forKey: "showSettingsButton")
viewController?.privacySettingsHelpText.hyperLink(originalText: viewController?.privacyHelpText ?? "", linkTextsAndTypes: [NSLocalizedString("_key_settings_help_", comment: ""): linkType.rawValue])

// Check that the correct view controller was pushed onto the navigation stack
XCTAssertNotNil(viewController?.navigationController?.visibleViewController is PrivacySettingsViewController)
}

func testPrivacyPolicyLinkType_NavigatesToPrivacyPolicyViewController() {

// Simulate tapping the "Privacy Policy" link type
let linkType = LinkType.privacyPolicy

viewController?.privacySettingsHelpText.hyperLink(originalText: viewController?.privacyHelpText ?? "", linkTextsAndTypes: [NSLocalizedString("_key_privacy_help_", comment: ""): linkType.rawValue])

// Check that the correct view controller was pushed onto the navigation
XCTAssertNotNil(viewController?.navigationController?.visibleViewController is PrivacyPolicyViewController)
}

func testCorrectImagePresentOnInitialPrivacySettingsViewController() {

// Check that the image view has the correct image
let expectedImage = UIImage(named: "dataPrivacy")
XCTAssertNotNil(expectedImage)
}

func testAcceptButtonHasBackgroundColor() {

// Check that the accept button has the correct background color
let expectedColor = NCBrandColor.shared.brand
XCTAssertEqual(viewController?.acceptButton.backgroundColor, expectedColor)

}

func testShowSaveSettingsButton() {

privacySettingsView.isShowSettingsButton = UserDefaults.standard.bool(forKey: "showSettingsButton")

XCTAssertTrue(privacySettingsView.isShowSettingsButton)

}

func testRequiredDataCollectionSectionExists() {
let form : XLFormDescriptor = XLFormDescriptor() as XLFormDescriptor
form.rowNavigationOptions = XLFormRowNavigationOptions.stopDisableRow

var section : XLFormSectionDescriptor
var row : XLFormRowDescriptor

// the section with the title "Required Data Collection"
row = XLFormRowDescriptor(tag: "ButtonDestinationFolder", rowType: "RequiredDataCollectionCustomCellType", title: "")
section = XLFormSectionDescriptor.formSection(withTitle: "")
section.footerTitle = NSLocalizedString("_required_data_collection_help_text_", comment: "")

// Verify that section was found
XCTAssertNotNil(row, "Expected 'Required Data Collection' section to exist in form.")
}

func testAnalysisDataCollectionSection() {

let form : XLFormDescriptor = XLFormDescriptor() as XLFormDescriptor
form.rowNavigationOptions = XLFormRowNavigationOptions.stopDisableRow
var section : XLFormSectionDescriptor
var row : XLFormRowDescriptor

// row with tag "AnalysisDataCollectionSwitch"
row = XLFormRowDescriptor(tag: "AnalysisDataCollectionSwitch", rowType: "AnalysisDataCollectionCustomCellType", title: "")
section = XLFormSectionDescriptor.formSection(withTitle: "")
section.footerTitle = NSLocalizedString("_analysis_data_acqusition_help_text_", comment: "")

// Assert that the row exists
XCTAssertNotNil(row, "Expected row with tag 'AnalysisDataCollectionSwitch' to exist in form.")

// Verify the switch is off
XCTAssertFalse(UserDefaults.standard.bool(forKey: "isAnalysisDataCollectionSwitchOn"), "Expected isAnalysisDataCollectionSwitchOn to be false.")
}


}
23 changes: 23 additions & 0 deletions iOSClient/Images.xcassets/dataPrivacy.imageset/Contents.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{
"images" : [
{
"filename" : "default copy@2x.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "default copy@3x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "default copy@4x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
21 changes: 21 additions & 0 deletions iOSClient/Main/Collection Common/NCCollectionViewCommon.swift
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,14 @@ class NCCollectionViewCommon: UIViewController, UIGestureRecognizerDelegate, UIS
preferences.animating.dismissDuration = 1.5

tipView = EasyTipView(text: NSLocalizedString("_tip_accountrequest_", comment: ""), preferences: preferences, delegate: self)

if(!UserDefaults.standard.bool(forKey: "isInitialPrivacySettingsShowed") || isApplicationUpdated()){
redirectToPrivacyViewController()

//set current app version
let appVersion = Bundle.main.infoDictionary?["CFBundleInfoDictionaryVersion"] as? String
UserDefaults.standard.set(appVersion, forKey: "CurrentAppVersion")
}

NotificationCenter.default.addObserver(self, selector: #selector(changeTheming), name: NSNotification.Name(rawValue: NCGlobal.shared.notificationCenterChangeTheming), object: nil)
}
Expand Down Expand Up @@ -249,6 +257,19 @@ class NCCollectionViewCommon: UIViewController, UIGestureRecognizerDelegate, UIS
// TIP
self.tipView?.dismiss()
}

func isApplicationUpdated() -> Bool{
let appVersion = Bundle.main.infoDictionary?["CFBundleInfoDictionaryVersion"] as? String ?? ""
let currentVersion = UserDefaults.standard.string(forKey: "CurrentAppVersion")
return currentVersion != appVersion
}

func redirectToPrivacyViewController(){
let storyBoard: UIStoryboard = UIStoryboard(name: "NCSettings", bundle: nil)
let newViewController = storyBoard.instantiateViewController(withIdentifier: "privacySettingsNavigation") as! UINavigationController
newViewController.modalPresentationStyle = .fullScreen
self.present(newViewController, animated: true, completion: nil)
}

func presentationControllerDidDismiss( _ presentationController: UIPresentationController) {

Expand Down
34 changes: 34 additions & 0 deletions iOSClient/Settings/AnalysisDataCollectionSwitch.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
//
// AnalysisDataCollectionSwitch.swift
// Nextcloud
//
// Created by A200073704 on 25/04/23.
// Copyright © 2023 Marino Faggiana. All rights reserved.
//

import UIKit

class AnalysisDataCollectionSwitch: XLFormBaseCell {

@IBOutlet weak var cellLabel: UILabel!
@IBOutlet weak var analysisDataCollectionSwitchControl: UISwitch!

override func awakeFromNib() {
super.awakeFromNib()
// Initialization code
analysisDataCollectionSwitchControl.addTarget(self, action: #selector(switchChanged), for: UIControl.Event.valueChanged)
}

override func configure() {
super.configure()
}

override func update() {
super.update()
}

@objc func switchChanged(mySwitch: UISwitch) {
self.rowDescriptor.value = mySwitch.isOn
}
}

73 changes: 73 additions & 0 deletions iOSClient/Settings/AnalysisDataCollectionSwitch.xib
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="17701" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES">
<device id="retina6_1" orientation="portrait" appearance="light"/>
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="17703"/>
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
<capability name="System colors in document resources" minToolsVersion="11.0"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
<view contentMode="scaleToFill" id="Sg3-qg-hfJ" userLabel="AutoUploadFolderCustomCell" customClass="AnalysisDataCollectionSwitch" customModule="Nextcloud" customModuleProvider="target">
<rect key="frame" x="0.0" y="0.0" width="397" height="93"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<switch opaque="NO" contentMode="scaleToFill" horizontalHuggingPriority="750" verticalHuggingPriority="750" contentHorizontalAlignment="center" contentVerticalAlignment="center" translatesAutoresizingMaskIntoConstraints="NO" id="EV8-vk-i59">
<rect key="frame" x="332" y="31" width="51" height="31"/>
</switch>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label" lineBreakMode="tailTruncation" numberOfLines="2" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="zGf-ZT-cHm">
<rect key="frame" x="20" y="36.5" width="310" height="20.5"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="b5P-C1-5KN" userLabel="topline">
<rect key="frame" x="0.0" y="0.0" width="397" height="1"/>
<color key="backgroundColor" systemColor="systemGray5Color"/>
<constraints>
<constraint firstAttribute="height" constant="1" id="qco-Ja-DRT"/>
</constraints>
</view>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="8ju-MK-Wzb" userLabel="bottomline">
<rect key="frame" x="0.0" y="92" width="397" height="1"/>
<color key="backgroundColor" systemColor="systemGray5Color"/>
<constraints>
<constraint firstAttribute="height" constant="1" id="UON-oh-6Jn"/>
</constraints>
</view>
</subviews>
<viewLayoutGuide key="safeArea" id="kfV-vm-sbb"/>
<color key="backgroundColor" systemColor="systemBackgroundColor"/>
<constraints>
<constraint firstItem="zGf-ZT-cHm" firstAttribute="leading" secondItem="kfV-vm-sbb" secondAttribute="leading" constant="20" id="4Gl-lH-YJO"/>
<constraint firstItem="kfV-vm-sbb" firstAttribute="bottom" secondItem="8ju-MK-Wzb" secondAttribute="bottom" id="DhT-9w-MSp"/>
<constraint firstItem="8ju-MK-Wzb" firstAttribute="leading" secondItem="Sg3-qg-hfJ" secondAttribute="leading" id="J8E-Jb-LZk"/>
<constraint firstItem="kfV-vm-sbb" firstAttribute="trailing" secondItem="EV8-vk-i59" secondAttribute="trailing" constant="16" id="NnC-WB-5yv"/>
<constraint firstItem="b5P-C1-5KN" firstAttribute="leading" secondItem="Sg3-qg-hfJ" secondAttribute="leading" id="c3O-WE-bN9"/>
<constraint firstAttribute="trailing" secondItem="b5P-C1-5KN" secondAttribute="trailing" id="eRd-Me-3Ev"/>
<constraint firstItem="b5P-C1-5KN" firstAttribute="top" secondItem="Sg3-qg-hfJ" secondAttribute="top" id="gUy-ON-aIX"/>
<constraint firstItem="zGf-ZT-cHm" firstAttribute="centerY" secondItem="Sg3-qg-hfJ" secondAttribute="centerY" id="j6c-8W-hv7"/>
<constraint firstItem="EV8-vk-i59" firstAttribute="centerY" secondItem="Sg3-qg-hfJ" secondAttribute="centerY" id="l3X-dN-8tp"/>
<constraint firstItem="EV8-vk-i59" firstAttribute="leading" secondItem="zGf-ZT-cHm" secondAttribute="trailing" constant="2" id="rh0-e5-fzQ"/>
<constraint firstAttribute="trailing" secondItem="8ju-MK-Wzb" secondAttribute="trailing" id="uq9-m3-WtQ"/>
</constraints>
<freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
<connections>
<outlet property="analysisDataCollectionSwitchControl" destination="EV8-vk-i59" id="ACv-q8-rPe"/>
<outlet property="cellLabel" destination="zGf-ZT-cHm" id="Z7F-IJ-Yz3"/>
</connections>
<point key="canvasLocation" x="125.36231884057972" y="189.17410714285714"/>
</view>
</objects>
<resources>
<systemColor name="systemBackgroundColor">
<color white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
</systemColor>
<systemColor name="systemGray5Color">
<color red="0.89803921568627454" green="0.89803921568627454" blue="0.91764705882352937" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</systemColor>
</resources>
</document>
Loading