예제 #1
0
func TestPrependHost(t *testing.T) {
	login := "******"
	abs := "http://server.com:6103/platinum/search"
	rel := "/platinum/search"
	testutils.Equals(t, abs, prependHost(login, abs))
	testutils.Equals(t, abs, prependHost(login, rel))
}
예제 #2
0
func TestSearchXMLComplex(t *testing.T) {
	type Listing struct {
		Business      string  `xml:"Business>RESIOWNS"`
		Approved      bool    `xml:"Listing>Approved"`
		MLS           string  `xml:"Listing>MLS"`
		Disclaimer    string  `xml:"Listing>Disclaimer"`
		Status        string  `xml:"Listing>Status"`
		ListingPrice  float64 `xml:"Listing>Price>ListingPrice"`
		OriginalPrice float64 `xml:"Listing>Price>OriginalPrice"`
		SellPrice     float64 `xml:"Listing>Price>SellingPrice"`
	}
	body := ioutil.NopCloser(strings.NewReader(standardXML))

	cr, err := NewStandardXMLSearchResult(body)
	testutils.Ok(t, err)

	var listings []Listing
	count, maxRows, err := cr.ForEach(minidom.ByName("PropertyListing"), func(elem io.ReadCloser, err error) error {
		if err != nil {
			return err
		}
		listing := Listing{}
		xml.NewDecoder(elem).Decode(&listing)
		listings = append(listings, listing)
		return err
	})
	testutils.Ok(t, err)
	testutils.Equals(t, true, maxRows)
	testutils.Equals(t, 10, count)
	testutils.Equals(t, 2, len(listings))
}
예제 #3
0
func TestSimple(t *testing.T) {
	doms := ioutil.NopCloser(strings.NewReader(example))
	parser := xml.NewDecoder(doms)
	listings := Listings{}
	// minidom isnt necessary but its crazy useful for massive streams
	md := minidom.MiniDom{
		StartFunc: func(start xml.StartElement) {
			switch start.Name.Local {
			case "Listings":
				attrs := map[string]string{}
				for _, v := range start.Attr {
					attrs[v.Name.Local] = v.Value
				}
				listings.ListingsKey = attrs["listingsKey"]
				listings.Version = attrs["version"]
				listings.VersionTimestamp = attrs["versionTimestamp"]
				listings.Language = attrs["lang"]
			case "Disclaimer":
				parser.DecodeElement(listings.Disclaimer, &start)
			}
		},
		// quit on the the xml tag
		EndFunc: minidom.QuitAt("Listings"),
	}
	err := md.Walk(parser, minidom.ByName("Listing"), ToListing(func(l Listing, err error) error {
		listings.Listings = append(listings.Listings, l)
		return err
	}))
	testutils.Ok(t, err)
	testutils.Equals(t, 1, len(listings.Listings))
	testutils.Equals(t, "http://www.somemls.com/lisings/1234567890", listings.Listings[0].ListingURL)
	testutils.Equals(t, "New Light Fixtures", *listings.Listings[0].Photos[1].Caption)
	testutils.Equals(t, "1100.0", listings.Listings[0].Expenses[2].Value.Value)
}
예제 #4
0
func TestCompactRowParsing(t *testing.T) {
	var col = `	A	B	C	D	E	F	`
	var row = `	1	2	3	4		6	`
	var delim = `	`
	headers := CompactRow(col).Parse(delim)
	values := CompactRow(row).Parse(delim)

	testutils.Equals(t, 6, int(len(headers)))
	testutils.Equals(t, 6, int(len(values)))
}
예제 #5
0
func TestMetaInfoIDMap(t *testing.T) {
	test := map[string]string{
		"ResourceID":      "rid",
		"LookupName":      "ln",
		"MetadataEntryID": "mid",
		"ClassName":       "cn",
		"ColumnGroupName": "cgn",
	}
	testutils.Equals(t, "rid", MIResource.ID(test))
	testutils.Equals(t, "ln", MILookup.ID(test))
	testutils.Equals(t, "cn", MIClass.ID(test))
	testutils.Equals(t, "cgn", MIColumnGroup.ID(test))
}
예제 #6
0
func verifyParseResources(t *testing.T, cm CompactMetadata) {
	resource := cm.Elements["METADATA-RESOURCE"][0]

	testutils.Equals(t, "1.12.30", resource.Attr["Version"])
	testutils.Equals(t, len(resource.CompactRows), 2)

	indexer := resource.Indexer()
	var rows []Row
	resource.Rows(func(i int, r Row) {
		rows = append(rows, r)
	})
	testutils.Equals(t, "ActiveAgent", indexer("ResourceID", rows[0]))
	testutils.Equals(t, "Tue, 3 Sep 2013 00:00:00 GMT", indexer("ValidationExternalDate", rows[1]))
}
예제 #7
0
func TestLoad(t *testing.T) {
	body := ioutil.NopCloser(strings.NewReader(raw))
	defer body.Close()
	parser := xml.NewDecoder(body)
	xml := RETSResponseWrapper{}

	err := parser.Decode(&xml)
	if err != io.EOF {
		testutils.Ok(t, err)
	}
	testutils.Equals(t, "Operation Successful", xml.ReplyText)

	testutils.Equals(t, "ABBA", xml.Metadata.MSystem.System.ID)
	testutils.Equals(t, "Property", string(xml.Metadata.MSystem.System.MResource.Resource[0].ResourceID))
}
예제 #8
0
func TestParseCompactData(t *testing.T) {
	body := ioutil.NopCloser(strings.NewReader(compact))
	decoder := DefaultXMLDecoder(body, false)
	token, err := decoder.Token()
	testutils.Ok(t, err)
	start, ok := token.(xml.StartElement)
	testutils.Assert(t, ok, "should be a start element")
	testutils.Equals(t, "METADATA-ELEMENT", start.Name.Local)
	cm, err := NewCompactData(start, decoder, "	")
	testutils.Ok(t, err)
	testutils.Equals(t, "METADATA-ELEMENT", cm.Element)
	testutils.Equals(t, "Dog", cm.Attr["Cat"])
	testutils.Equals(t, 2, len(cm.CompactRows))
	testutils.Equals(t, 2, len(cm.Columns()))
}
예제 #9
0
func TestSearchXML(t *testing.T) {
	body := ioutil.NopCloser(strings.NewReader(standardXML))

	cr, err := NewStandardXMLSearchResult(body)
	testutils.Ok(t, err)

	var listings []io.ReadCloser
	count, maxRows, err := cr.ForEach(minidom.ByName("PropertyListing"), func(elem io.ReadCloser, err error) error {
		listings = append(listings, elem)
		return err
	})
	testutils.Ok(t, err)
	testutils.Equals(t, true, maxRows)
	testutils.Equals(t, 10, count)
	testutils.Equals(t, 2, len(listings))
}
예제 #10
0
func verifyParseLookup(t *testing.T, cm CompactMetadata) {
	mdata := cm.Elements["METADATA-LOOKUP"][0]

	testutils.Equals(t, "TaxHistoricalDesignation", mdata.Attr["Resource"])
	testutils.Equals(t, "1.12.29", mdata.Attr["Version"])
	testutils.Equals(t, len(mdata.CompactRows), 4)

	indexer := mdata.Indexer()
	var row []Row
	mdata.Rows(func(i int, r Row) {
		row = append(row, r)
	})

	testutils.Equals(t, "COUNTIES_OR_REGIONS", indexer("LookupName", row[0]))
	testutils.Equals(t, "Tue, 3 Sep 2013 00:00:00 GMT", indexer("Date", row[3]))
}
예제 #11
0
func TestSearchCompactNoEof(t *testing.T) {
	rets := `<RETS ReplyCode="20201" ReplyText="No Records Found." ></RETS>`
	body := ioutil.NopCloser(strings.NewReader(rets))

	cr, err := NewCompactSearchResult(body)
	testutils.Ok(t, err)
	testutils.Equals(t, StatusNoRecords, cr.Response.Code)
}
예제 #12
0
func TestCreateHa2(t *testing.T) {
	method, uri := "GET", "/platinum/login"

	expected := "1b11c4ebed4a67753078be8020ea9d19"
	actual := createNoQopDigest().createHa2(method, uri, md5.New())

	testutils.Equals(t, expected, actual)
}
예제 #13
0
func TestSystem(t *testing.T) {
	body := ioutil.NopCloser(strings.NewReader(raw))
	defer body.Close()

	extractor := &Extractor{Body: body}
	response, err := extractor.Open()

	testutils.Ok(t, err)
	testutils.Equals(t, "Operation Successful", response.ReplyText)

	xml := MSystem{}
	err = extractor.DecodeNext("METADATA-SYSTEM", &xml)
	if err != io.EOF {
		testutils.Ok(t, err)
	}
	testutils.Equals(t, "ABBA", xml.System.ID)
	testutils.Equals(t, "Property", string(xml.System.MResource.Resource[0].ResourceID))
}
예제 #14
0
func TestCompactEntry(t *testing.T) {
	body := ioutil.NopCloser(strings.NewReader(compact))
	decoder := DefaultXMLDecoder(body, false)
	token, err := decoder.Token()
	testutils.Ok(t, err)
	start, ok := token.(xml.StartElement)
	testutils.Assert(t, ok, "should be a start element")
	cm, err := NewCompactData(start, decoder, "	")
	testutils.Ok(t, err)
	type Test struct {
		ResourceID, Standardname string
	}
	row1 := Test{}
	maps := cm.Entries()
	maps[0].SetFields(&row1)
	testutils.Equals(t, "ActiveAgent", row1.ResourceID)
	testutils.Equals(t, "ActiveAgent", row1.Standardname)
}
예제 #15
0
func TestSearchXMLParseSearchQuit(t *testing.T) {
	noEnd := strings.Split(standardXML, "Commercial")[0]
	body := ioutil.NopCloser(strings.NewReader(noEnd))

	cr, err := NewStandardXMLSearchResult(body)
	testutils.Ok(t, err)

	var listings [][]byte
	count, maxRows, err := cr.ForEach(minidom.ByName("PropertyListing"), func(elem io.ReadCloser, err error) error {
		tmp, _ := ioutil.ReadAll(elem)
		listings = append(listings, tmp)
		return err
	})
	testutils.NotOk(t, err)
	testutils.Equals(t, false, maxRows)
	testutils.Equals(t, 10, count)
	testutils.Equals(t, 1, len(listings))
}
예제 #16
0
func TestCreateHa1Md5(t *testing.T) {
	username := "******"
	password := "******"
	cnonce := "6ac2c2eee85f5c33"

	expected := "5c0da895491be93b455ebb56f7ae0a9f"
	actual := createNoQopDigest().createHa1(username, password, cnonce, md5.New())

	testutils.Equals(t, expected, actual)
}
예제 #17
0
func TestSearchCompactParseSearchQuit(t *testing.T) {
	noEnd := strings.Split(compactDecoded, "<MAXROWS/>")[0]
	body := ioutil.NopCloser(strings.NewReader(noEnd))

	cr, err := NewCompactSearchResult(body)
	testutils.Ok(t, err)

	rowsFound := 0
	cr.ForEach(func(data Row, err error) error {
		if err != nil {
			testutils.Assert(t, strings.Contains(err.Error(), "EOF"), "found something not eof")
			return err
		}
		testutils.Equals(t, "1,2,3,4,,6", strings.Join(data, ","))
		rowsFound++
		return nil
	})
	testutils.Equals(t, 8, rowsFound)
}
예제 #18
0
func TestSearchCompactEmbeddedRetsStatus(t *testing.T) {
	rets := `<?xml version="1.0" encoding="UTF-8" ?>
			<RETS ReplyCode="0" ReplyText="Operation Successful">
			<RETS-STATUS ReplyCode="20201" ReplyText="No matching records were found" />
			</RETS>`
	body := ioutil.NopCloser(strings.NewReader(rets))
	cr, err := NewCompactSearchResult(body)
	testutils.Ok(t, err)
	testutils.Equals(t, StatusNoRecords, cr.Response.Code)
}
예제 #19
0
func TestCreateResponseQopAuth(t *testing.T) {
	nc := "00000001"
	cnonce := "6ac2c2eee85f5c33"
	ha1 := "5c0da895491be93b455ebb56f7ae0a9f"
	ha2 := "1b11c4ebed4a67753078be8020ea9d19"

	expected := "28552064c4cde9a3af7610e7ae286d50"
	actual := createAuthDigest().createResponse(ha1, ha2, nc, cnonce, md5.New())

	testutils.Equals(t, expected, actual)
}
예제 #20
0
func TestMetaInfoIDStruct(t *testing.T) {
	type TestStruct struct {
		ResourceID      string
		LookupName      string
		MetadataEntryID string
		ClassName       string
		ColumnGroupName string
	}
	test := &TestStruct{
		ResourceID:      "rid",
		LookupName:      "ln",
		MetadataEntryID: "mid",
		ClassName:       "cn",
		ColumnGroupName: "cgn",
	}
	testutils.Equals(t, "rid", MIResource.ID(test))
	testutils.Equals(t, "ln", MILookup.ID(test))
	testutils.Equals(t, "cn", MIClass.ID(test))
	testutils.Equals(t, "cgn", MIColumnGroup.ID(test))
}
예제 #21
0
func TestCreateResponseNoQop(t *testing.T) {
	nc := "00000001"
	cnonce := "6ac2c2eee85f5c33"
	ha1 := "5c0da895491be93b455ebb56f7ae0a9f"
	ha2 := "1b11c4ebed4a67753078be8020ea9d19"

	expected := "5f8d366fb430e9b395a84dba52247a35"
	actual := createNoQopDigest().createResponse(ha1, ha2, nc, cnonce, md5.New())

	testutils.Equals(t, expected, actual)
}
예제 #22
0
func TestSystemHierarchyCount(t *testing.T) {
	count := func(MetaInfo) int { return 0 }
	count = func(mi MetaInfo) int {
		counter := 1
		for _, c := range mi.Child {
			counter = counter + count(c)
		}
		return counter
	}
	testutils.Equals(t, 25, count(MISystem))
}
예제 #23
0
func TestDigest(t *testing.T) {
	username, password := "******", "passwd"

	expected := `Digest username="******", realm="*****@*****.**", nonce="31333739363738363932323632201e00230a639db77779b354d601ee5d2e", uri="/platinum/login", response="5f8d366fb430e9b395a84dba52247a35", algorithm="MD5", opaque="6e6f742075736564"`

	method, uri := "GET", "/platinum/login"

	actual := createNoQopDigest().CreateDigestResponse(username, password, method, uri)

	testutils.Equals(t, expected, actual)
}
예제 #24
0
func TestSearchCompactBadChar(t *testing.T) {
	rets := `<?xml version="1.0" encoding="UTF-8" ?>
			<RETS ReplyCode="0" ReplyText="Operation Successful">
			<COUNT Records="1" />
			<DELIMITER value = "09"/>
			<COLUMNS>	A	B	C	D	E	F	</COLUMNS>
			<DATA>	1` + "\x0b" + `1	2	3	4		6	</DATA>

			</RETS>`
	body := ioutil.NopCloser(strings.NewReader(rets))

	cr, err := NewCompactSearchResult(body)
	testutils.Ok(t, err)
	testutils.Equals(t, StatusOK, cr.Response.Code)
	counter := 0
	cr.ForEach(func(row Row, err error) error {
		testutils.Ok(t, err)
		testutils.Equals(t, "1 1,2,3,4,,6", strings.Join(row, ","))
		counter = counter + 1
		return nil
	})
}
예제 #25
0
func TestParseCapabilitiesRelativeUrls(t *testing.T) {
	body :=
		`<RETS ReplyCode="0" ReplyText="V2.7.0 2315: Success">
	<RETS-RESPONSE>
	MemberName=Threewide Corporation
	User=2000343, Association Member Primary:Login:Media Restrictions:Office:RETS:RETS Advanced:RETS Customer:System-MRIS:MDS Access Common:MDS Application Login, 90, TURD1
	Broker=TWD,1
	MetadataVersion=1.12.30
	MinMetadataVersion=1.1.1
	OfficeList=TWD;1
	TimeoutSeconds=1800
	Login=/platinum/login
	Action=/platinum/get?Command=Message
	Search=/platinum/search
	Get=/platinum/get
	GetObject=/platinum/getobject
	Logout=/platinum/logout
	GetMetadata=/platinum/getmetadata
	ChangePassword=/platinum/changepassword
	X-SampleLinks=/rets2_2/Links
	X-SupportSite=http://flexmls.com/rets/
	X-NotificationFeed=http://example.com/atom/feed/private/atom.xml
	</RETS-RESPONSE>
	</RETS>`
	urls, err := parseCapability(
		ioutil.NopCloser(strings.NewReader(body)),
		"http://server.com:6103/platinum/login",
	)
	testutils.Ok(t, err)

	testutils.Equals(t, urls.Response.Text, "V2.7.0 2315: Success")
	testutils.Equals(t, urls.Response.Code, StatusOK)
	testutils.Equals(t, urls.Login, "http://server.com:6103/platinum/login")
	testutils.Equals(t, urls.GetMetadata, "http://server.com:6103/platinum/getmetadata")
	testutils.Equals(t, "http://server.com:6103/rets2_2/Links", urls.AdditionalURLs["X-SampleLinks"])
}
예제 #26
0
func TestFieldTransfer(t *testing.T) {
	type Tester struct {
		Bob string
		foo string
		Baz string
	}
	test := &Tester{}
	FieldTransfer(map[string]string{
		"Bob": "foo",
		"Foo": "bar",
		"baz": "blah",
	}).To(test)
	testutils.Equals(t, "foo", test.Bob)
	testutils.Assert(t, "" == test.foo, "shouldnt be able to set lower case fields")
	testutils.Assert(t, "blah" == test.Baz, "should be case insensitive")
}
예제 #27
0
func TestDigestQopAuth(t *testing.T) {
	username, password := "******", "passwd"

	wwwAuthenticate := `Digest realm="*****@*****.**",nonce="cbbaac704d6762fa2e4c37bb84ffddb8",opaque="77974390-589f-4ec6-b67c-4a9fc096c03f",qop="auth"`
	expected := `Digest username="******", realm="*****@*****.**", nonce="cbbaac704d6762fa2e4c37bb84ffddb8", uri="/rets/login", response="3b2ce903001cf00a264c69674d691526", qop=auth, nc=00000001, cnonce="6ac2c2eee85f5c33", algorithm="MD5", opaque="77974390-589f-4ec6-b67c-4a9fc096c03f"`

	method, uri := "GET", "/rets/login"
	cnonce := "6ac2c2eee85f5c33"

	dig, err := NewDigest(wwwAuthenticate)
	if err != nil {
		t.Fail()
	}
	actual := dig.computeAuthorization(username, password, method, uri, cnonce)

	testutils.Equals(t, expected, actual)
}
예제 #28
0
func TestCreateHa1Md5Sess(t *testing.T) {
	username := "******"
	password := "******"
	cnonce := "6ac2c2eee85f5c33"

	wwwAuthenticate := `Digest realm="*****@*****.**", nonce="31333739363738363932323632201e00230a639db77779b354d601ee5d2e", opaque="6e6f742075736564, algorithm="MD5-sess"`

	digest, err := NewDigest(wwwAuthenticate)
	if err != nil {
		t.Fail()
	}

	expected := "f1843845124dcba66fef064f5aa7a782"
	actual := digest.createHa1(username, password, cnonce, md5.New())

	testutils.Equals(t, expected, actual)
}
예제 #29
0
func TestProcessResponseBodyNoConnectTime(t *testing.T) {
	actual, err := processResponseBody(
		ioutil.NopCloser(strings.NewReader(
			`<RETS ReplyCode="0" ReplyText="Logging out">
						 				<RETS-RESPONSE>
						 				Billing=Im Billing You
						 				SignOffMessage=Goodbye
						 				</RETS-RESPONSE>
		                 				</RETS>`,
		)))

	if err != nil {
		t.Fail()
	}

	expected := &LogoutResponse{ReplyCode: StatusOK, ReplyText: "Logging out", Billing: "Im Billing You", SignOffMessage: "Goodbye"}

	testutils.Equals(t, expected, actual)
}
예제 #30
0
func TestParseChallenge(t *testing.T) {
	wwwAuthenticate := `Digest realm="*****@*****.**", nonce="31333739363738363932323632201e00230a639db77779b354d601ee5d2e", opaque="6e6f742075736564"`

	digest, err := NewDigest(wwwAuthenticate)
	if err != nil {
		t.Fail()
	}

	expected := &Digest{
		Realm:      "*****@*****.**",
		Nonce:      "31333739363738363932323632201e00230a639db77779b354d601ee5d2e",
		Algorithm:  "MD5",
		Opaque:     "6e6f742075736564",
		Qop:        "",
		NonceCount: 1,
	}

	testutils.Equals(t, expected, digest)
}